Sizing images and video without layout shift

Development · 6 min read

That jarring jump when a page's content shoves itself downward as an image finishes loading is layout shift, and it is one of the most common, most fixable problems in front-end development. A handful of CSS properties, used together deliberately, eliminate it almost entirely.

Why layout shift happens in the first place

Before an image or video has finished loading, the browser often does not know its dimensions, so it renders the surrounding content as if that space does not exist. When the media finally loads and reveals its actual size, everything below it jumps to make room.

This matters for more than just visual polish. Cumulative Layout Shift (CLS) is one of Google's Core Web Vitals, directly affecting search ranking, and it is also one of the more genuinely annoying user experience problems, since it can cause people to misclick a button that moved at the exact moment they tapped it.

Reserving space with the aspect-ratio property

The CSS aspect-ratio property lets you tell the browser the width-to-height relationship of an element before its content has loaded, so it can reserve the correct amount of space immediately, before any image data has arrived.

Setting aspect-ratio: 16 / 9 on an image or a video container, for example, tells the browser to calculate its height from its width using that ratio, reserving the right amount of space in the layout from the very first render, well before the media itself is available.

This is a genuine improvement over older techniques like the padding-top percentage hack, which achieved a similar effect but required an extra wrapper element and was noticeably harder to read and maintain.

Setting width and height attributes still matters

Even with aspect-ratio available in CSS, it is still worth setting width and height attributes directly on img and video elements in your HTML, since browsers use these to calculate the correct aspect ratio automatically without needing separate CSS at all.

Modern browsers combine the HTML width and height attributes with the image's own natural dimensions to reserve space automatically as soon as the HTML parses, which is one of the simplest and most effective fixes available, and it costs nothing beyond writing two extra attributes.

If you do need a different displayed ratio than the image's native one, layering an explicit aspect-ratio in CSS on top of the HTML attributes covers that case cleanly, using the attributes as a fallback for anywhere the CSS has not loaded yet.

srcset and responsive image sizing

The srcset attribute lets the browser choose the most appropriate image file from a set of options based on the viewport size and screen density, rather than forcing every device to download the same, potentially oversized image.

Combined with the sizes attribute, which tells the browser how large the image will actually be displayed at different viewport widths, this avoids sending a large desktop-resolution image to a small mobile screen, saving bandwidth and improving load time considerably.

srcset addresses a different problem to aspect-ratio, though the two work well together: srcset controls which file loads, while aspect-ratio and width/height attributes control how much layout space is reserved for whichever file that turns out to be.

object-fit for consistent cropping

Once you have fixed a container's dimensions with aspect-ratio, the image inside it needs a way to fill that space sensibly if its own native ratio does not match exactly. The object-fit property controls this: cover scales and crops the image to fill the box completely, while contain scales it down to fit entirely within the box, leaving empty space if the ratios do not match.

object-fit: cover is the most common choice for photography in a fixed-ratio card or hero layout, since it avoids distortion or stretching by cropping intelligently rather than squashing the image into the wrong shape.

Pairing object-fit with object-position lets you control which part of the image stays visible when cropping occurs, which matters for photos where the important subject is not perfectly centred.

Video needs the same treatment as images

Video elements suffer from exactly the same layout shift problem as images, and the same fixes apply directly: set width and height attributes, or an explicit aspect-ratio in CSS, so the player's space is reserved before the video metadata has loaded.

Embedded third-party video, like an iframe-based player, is trickier since you do not control its internal HTML, but wrapping the iframe in a container with a fixed aspect-ratio and setting the iframe itself to fill that container with width and height set to 100% solves the same problem effectively.

Putting it together in a real layout

A solid modern pattern is to give an image a defined aspect-ratio in CSS, set object-fit: cover so it always fills its box regardless of its native dimensions, include width and height attributes for early browser hinting, and use srcset and sizes so the right file loads for the right device.

None of these techniques alone completely eliminates layout shift, but combined, they cover the two separate causes: not knowing the media's shape ahead of time, and loading a file that is a different actual size than the space it needs to fill.

Checking whether it worked

Use your browser's performance or Lighthouse panel to measure Cumulative Layout Shift directly, and watch the page load on a throttled connection, since layout shift issues are often invisible on a fast local network but glaringly obvious on a slower mobile connection where images take longer to arrive.

If you are converting design measurements between formats while building these layouts, a unit-calculator or an aspect-ratio tool can save time working out exact ratios or converting between pixel dimensions and simplified ratios like 16:9 or 4:3.

Common questions

What is the single most effective fix for image-related layout shift?
Setting width and height attributes on every img element, combined with a CSS aspect-ratio where the displayed ratio differs from the image's native one. This gives the browser everything it needs to reserve the correct layout space immediately, before the image file itself has even started downloading.
Do I still need the old padding-top percentage hack?
No, not for modern browsers. The aspect-ratio CSS property achieves the same space-reserving effect far more simply, without needing an extra wrapper element or the somewhat confusing percentage-based maths the older technique required. It is safe to migrate away from the hack in current projects.
What is the difference between object-fit: cover and contain?
Cover scales an image up or down and crops it as needed so it completely fills its container with no empty space, potentially cutting off some edges. Contain scales the image to fit entirely inside the container without cropping, which can leave visible empty space if the image and container ratios do not match.
Does srcset help with layout shift directly?
Not directly, since it is primarily about loading an appropriately sized file for performance rather than reserving layout space. However, it works well alongside aspect-ratio and width/height attributes, which handle the layout-space problem while srcset handles which specific file gets downloaded for a given device.
How do I stop an embedded video iframe from causing layout shift?
Wrap the iframe in a container element with a fixed aspect-ratio set in CSS, then set the iframe's own width and height to 100% so it fills that container completely. This reserves the correct space in the layout immediately, since the wrapper's dimensions do not depend on the iframe's content loading first.

Tools for this

Keep reading