The leaner/faster your site is, the more noticeable/painful image loading becomes, especially with hero images. Layout getting recalculated when each image arrives results in a spastic hurk-jerk page reflow. This bothered us enough on DayTrip to find a fix.

Common workarounds tend to be load a grey placeholder.gif or even a blurry image, then lazyload the actual image in later. Lazyloading gives me the heebie-jeebies, since I’ve only ever seen it successfully work once in my whole entire lifetime. I just want a predetermined box that the browser fills with an image.

Here’s a demo of what we came up with (try your hardest to ignore the FOIT 😖).

Intrinsic Ratios aren’t new, but paired with the <picture> element it’s a beautiful little technique with little-to-no extra markup:

<picture class="intrinsic intrinsic--square">
  <source media="(min-width: 500px)" srcset="large.jpg">
  <img class="intrinsic-item" srcset="small.jpg" alt="">
</picture>

I built out a little “Intrinsic” Sass component that draws intrinsic ratio box to match your image’s aspect ratio.

// intrinsic.scss ------------------------
// An Intrinsic Ratio Component
// ---------------------------------------

.intrinsic {

  // Make sure <picture> wrapper is set to block
  // Max-width is governed by parentNode
  display: block;

  // Intrinsic Ratio Box
  position: relative;
  height: 0;
  width: 100%;
  padding-top: 100%; // Default to square

  // Custom Styling
  background: #f0f0f0;

  // Add as many ratios as you'd like...
  &.intrinsic--square {
    padding-top: 100%;
  }

  &.intrinsic--4x3 {
    padding-top: 75%;
  }

  &.intrinsic--16x9 {
    padding-top: 56.25%;
  }

  // Force the item to fill the intrinsic box
  .intrinsic-item {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }
}

It could be used for video embeds as well. It doesn’t cover the use case that your responsive images change aspect ratio, you’d need a custom modifier class for something like that.

Here’s an example of it working inside a rudimentary Media component. You’ll probably want to View it full on CodePen and throttle your connection.

See the Pen Intrinsic Ratio Image Placeholders with the Picture Element by Dave Rupert (@davatron5000) on CodePen.

So far I like it. Users might see that grey box, but the document doesn’t hurk-jerk and I’m not lying about content image sources. Web Inspector’s “Enable Paint flashing” seems to confirm with way less green flashing.

Paired that with Progressive JPEGs I get a (not-so) lazy-loading effect that has way less technical overhead, in my humble opinion. If you find this helpful or you already wrote a blog post about this, let me know!