Image with fixed maximum width and height, original aspect ratio: avoid layout shift

Viewed 49

Say I have this html:

<img class="myimg" id="img1" src="http://placekitten.com/300/200" width="300" height="200">
<img class="myimg" id="img2" src="http://placekitten.com/400/600" width="400" height="600">
...

and this CSS:

.myimg {
  width: auto;
  height: auto;
  max-width: 200px;
  max-height: 200px;
}

This ensures that the image is rescaled if it exceeds any of the dimensions, and the original aspect ratio is preserved.

The html code is generated dynamically (e.g. PHP) and the server-side code is capable of getting the size of each image, so I can have the width and height properties to match the actual size of each image.

What I want is to have the space occupied by the image to be predetermined so that it can be rendered at the final size since the beginning, and avoid causing a jump (layout shift) when the image is loaded.

That's the reason I add the width and height attributes in the html but it does not work. In fact, whatever the values of the width and height attributes are, or if I omit them, the result is the same. The problem is that the image doesn't occupy any space until it's loaded.

Removing width: auto and height: auto fixes that, but it causes another issue: images that exceed only one of the two dimensions will be squeezed in either direction, that is, lose their aspect ratio.

So, how do I achieve all these goals:

  • preserve original aspect ratio
  • ensure maximum width and height (rescale only if needed)
  • tell the browser the native size of the image so it can compute the rendered size before the image is loaded and therefore avoid any layout shift.

I do not want to compute the final image size on the server side. I know that if I do that I can easily solve the problem by using style attributes on each img element.

1 Answers

Web performance advocates have often advised to add dimensions to your images for best performance to allow the page to be laid out with the appropriate space for the image, before the image itself has been downloaded. This avoids a layout shift as the image is downloaded.

Well, a dirty, little, secret — not that well-known outside the hard-core web performance advocates — is that, until recently, this actually didn’t make a difference in a lot of cases, as we’ll see below. However, adding width and height attributes to your markup have become useful again after some recent changes in the CSS world, and the quick adoption of these changes by the most popular web browsers.

RECOMMENDED READING

The CSS contain property gives you a way to explain your layout to the browser, so performance optimizations can be made. However, it does come with some side effects in terms of your layout. Take for example this simple page:

<h1>Your title</h1>
<p>Introductory paragraph.</p>
<image src="hero_image.jpg" alt="">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit…</p>
Related