What if we got aspect-ratio sized images by doing almost nothing?

Avatar of Chris Coyier
Chris Coyier on (Updated on )

Say you have an image you’re using in an <img> that is 800×600 pixels. Will it actually display as 800px wide on your site? It’s very likely that it will not. We tend to put images into flexible container elements, and the image inside is set to width: 100%;. So perhaps that image ends up as 721px wide, or 381px wide, or whatever. What doesn’t change is that image’s aspect ratio, lest you squish it awkwardly (ignoring the special use-case object-fit scenario).

The main point is that we don’t know how much vertical space an image is going to occupy until that image loads. This is the cause of jank! Terrible jank! It’s everywhere and it’s awful.

Update! This actually happened. So all you have to do is put the correct natural width and height attributes on images and they will load without jank, even if CSS makes the image fluid with. So do it like: <img src="image.jpg" width="800" height="600">

There are ways to create aspect-ratio sized boxes in HTML/CSS today. None of the options are particularly elegant because they rely on the “hack” of setting a zero height and pushing the boxes height with padding. Wouldn’t it be nicer to have a platform feature to help us here? The first crack at fixing this problem that I know about is an intrinsicsize attribute. Eric Portis wrote about how this works wonderfully in Jank-Free Image Loads.

We’d get this:

<img src="image.jpg" intrinsicsize="800x600" />

This is currently behind a flag in Chrome 71+, and it really does help solve this problem.

But…

The intrinsicsize property is brand new. It will only help on sites where the developers know about it and take the care to implement it. And it’s tricky! Images tend to be sized arbitrarily, and the intrinsicsize attribute will need to be custom on every image to be accurate and do its job. That is, if it makes it out of standards at all.

There is another possibility! Eric also talked about the aspect-ratio property in CSS as a potential solution. It’s also still just a draft spec. You might say, but how is this helpful? It needs to be just as bespoke as intrinsicsize does, meaning you’d have to do it as inline styles to be helpful. Maybe that’s not so bad if it solves a big problem, but inline styles are such a pain to override and it seems like the HTML attribute approach is more inline with the spirit of images. Think of how srcset is a hint to browsers for what images are available to download, allowing the browser to pick the best one for the scenario. Telling the browser about the aspect-ratio upfront is similarly useful.

I heard from Jen Simmons about an absolutely fantastic way to handle this: put a default aspect ratio into the UA stylesheet based on the elements existing width and height attributes. Like this:

img, video {
  aspect-ratio: attr(width) / attr(height);
}

Let that soak in.

Now if you already have:

<img src="image.jpg" width="800" height="600" />

It automatically has the correct aspect ratio as the page loads. That’s awesome.

  1. It’s easy to understand.
  2. A ton of the internet already has these attributes sitting on their images.
  3. New developers will have no trouble understanding this, and old developers will be grateful there is little (if any) work to do here.

I like the idea of the CSS feature. But I like 100 times more the idea of putting it into the UAUA stylesheet is no small thing to consider — and I’m not qualified to understand all the implications of that — but it feels like a very awesome thing at first consideration.

Jen has a ticket open for people to voice their thoughts and links to the bug ticket where Firefox is going to test this out to see how it goes.