Ian Duffy Logo

Handling Layout shift with img and picture tag

12 July 2024

4 mins read

A lot of us have probably been there when you are about to click on an button on a web page or reading some text when suddenly the page has shifted due to content loading in such as image or ad, this is called layout shift.

Layout shift can cause users to lose their place on a web page or click on something they didn't want to that moves them away from the page, which could lead to frustrated users.

This is a part of the reason that Google added Cumulative Layout Shift (CLS) to its core web vitals metrics as a part of how Google see websites based on web performance.

So how do images cause layout shifts?

When a web page starts to load an image the browser doesn't know the actual dimensions of the image, which means the page can't reserve space for any images, so as the browser downloads it discovers the image width and height it causing content below to be pushed down.

Reserving space for img elements

This is where the width and height attributes for the img element come in, we can tell the browser the width and height of the image that will be loading.

Alone these attributes tell the image what width and height to take, which can cause the image to be squashed or stretched to fit

So how can we handle this in responsive images and multiple breakpoints, using CSS we give images the following CSS:

img {
  width: 100%; 
  height: auto;
}

The first line tells the img element to use the full container width rather than what is stated in the width attribute. The second line tells the img element to automatically take the height it needs, without this say the actual image once rendered was only 400px height but the browser has reserved 600px, so the image would get stretched to use the space up.

Note: The actual rendered images taking up less height size will cause a layout shift which is why it important to get close as possible to reduce the shift. The less amount the page shifts the better the score is.

These attributes are vital in how the image element works in responsive design and building for multiple devices. The browser can use these to work out the space it needs at multiple sizes by figuring out the aspect ratio based on the width of the container but say the height attribute doesn't match the actual image aspect ratio it stops the image from squashing or stretching.

Using these methods means an img element with 400px width and 400px height, but the rendered width of 600px, the browser will reserve space of 600px in the browser.

Reserving space for picture elements

In the picture element, you can supply the browser with multiple image sources which can range from different image support for modern image formats, dark and light modes and different browser sizes. Images especially hero elements can have very different aspect ratios for readability with devices.

In the last few years, HTML spec and modern browsers have added the width and height attributes to the source element, this means we can give each independent source at different aspect ratios where needed. This meant we can the same layout shift improvement across multiple devices.

<picture>
  <!--  Desktop image -->
  <source width='1200' height='900' media="(min-width: 1024px)"  />
  <!-- Tablet Image  -->
  <source width='800' height='600' media="(min-width: 600px)"  />
  <!-- Mobile Image at 1/1 aspect ratio -->
  <img width='600' height='600' />
</picture>

Other Elements

It not just images that cause layout shift on websites, they are other elements such as the video element that works similar to the picture element via source elements, and iframe element that is similar to img element.

However sometimes custom sections of a website such as personalised content to a user based on stuff like previous search results, in this case you can use aspect ratio css property on the container or create individuals fake items with similar aspect ratio of the actual content.