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!