Set image width and height to stop layout shift
Why every image needs width and height attributes, how browsers turn them into reserved space, and how to fix images without them in a CMS or a builder.
In this guide
The problem
When a browser reads the HTML and finds an img without a size, it does not know how tall the image will be. It draws the text around it as if the image were not there. When the file arrives, the browser measures it, makes room, and pushes everything below it down. The visitor, who may have started reading, sees the page jump. This is a layout shift, and it counts against your CLS.
It is also common. The 2025 Web Almanac measured 62% of mobile pages with at least one unsized image, against 65% on desktop. The typical page had two of them, and the worst tenth had 23 on mobile and 26 on desktop. Lighthouse reports it as "Image elements do not have explicit width and height".
The fix
Add the attributes, with the intrinsic size of the image file, in pixels, without units:
<img src="/img/office.avif" width="1200" height="800" alt="Our office reception">Then keep the image fluid with CSS, because the attributes alone would force a fixed size on small screens:
img {
max-width: 100%;
height: auto;
}What happens: the browser reads width="1200" and height="800" before the file arrives and calculates an aspect ratio of 3 to 2. It then applies that ratio as the image's default aspect-ratio, and the CSS decides the width. height: auto tells the browser to calculate the height from the width and that ratio. The space is reserved at the right shape for any screen width, and when the file arrives, it fits exactly. The browsers do this from the attributes themselves, so the HTML alone is enough: you do not need to write the aspect ratio in your CSS.
Why not set the size in CSS only?
You can reserve space with CSS, and sometimes you must, but the attributes have an advantage: they are in the HTML. The browser reads them as soon as it reads the tag, before the stylesheet has arrived, so the space is reserved from the very first layout. A size that lives only in a stylesheet is unknown until that file has loaded, and a page whose CSS loads late can still shift. The attributes cost nothing, work without any CSS, and are the first line of defense. Use CSS aspect-ratio for the boxes that have no attributes to carry it.
It must be the right size
The numbers must match the file's proportions. If the attributes say 1200 by 800 and the file is 1200 by 900, the browser reserves the wrong shape and the page still shifts a little when the file loads. Use the real dimensions of the file you serve, or of the largest one in the srcset list.
For responsive images, set the attributes to the dimensions of the largest source, so the proportion is right. The width of the image on screen is set by CSS and the sizes attribute; the width and height are only used for the shape. All the sources in a srcset should have the same proportions. If you change the shape on small screens, use the picture element with source elements that carry their own width and height.
Other boxes that need a shape
- Videos. Add
widthandheighttovideoelements too, and aposterof the same shape. - Embeds and iframes. They have no intrinsic shape. Put them in a container with
aspect-ratio: 16 / 9(or the right proportion). - Background images and hero areas. A CSS background has no size of its own. Give the container a
min-heightor anaspect-ratio. - SVGs. An inline SVG with a
viewBoxand a width in CSS gets its ratio from the viewBox. An SVG in animgneeds the attributes like any other image. - Lazy-loaded images. An image that has not loaded has no size at all, so the attributes matter even more. See lazy loading.
Fixing it in a CMS or a page builder
On a hand-built site you edit the HTML. On a CMS, you rarely can.
- WordPress. Images inserted through the editor carry width and height. The missing ones come from the theme, from a page builder, from custom HTML, or from a plugin that rewrites the markup. Check the HTML of the page, and look in the theme's templates and the builder's image settings. Core's loading optimizations (lazy loading and priority) only apply to images that have both attributes.
- Page builders. Most have an option for the image size or the aspect ratio of an image widget; use it, and avoid "auto" height with no placeholder.
- Hosted builders and store themes. Look at the theme's image settings, which often have a "fixed ratio" option for product and collection images.
- A CDN or image service. Many can add the attributes on the fly, or serve images at a fixed size and ratio.
How to find the images that are missing them
- Run Lighthouse. The audit lists the images that lack the attributes, with the element.
- Search the HTML. In DevTools, search the Elements panel for
<imgand check each one. For a site with many pages, a crawler or a script can list every image tag without both attributes. - Watch the page load on a throttled connection. An image without a size shows as a jump.
How to find the numbers, and the missing ones, in the browser
To read the real size of an image, open the browser's console on the page and ask for it. Every image element knows the size of the file it loaded:
const img = document.querySelector('img');
console.log(img.naturalWidth, img.naturalHeight);To list every image on the page that is missing one of the two attributes, run this in the console. It prints the address of each image to fix:
[...document.images]
.filter((img) => !img.getAttribute('width') || !img.getAttribute('height'))
.map((img) => img.currentSrc || img.src);For a hand-built page, the steps are short: find the list, open each image's file to check its dimensions, add the two attributes, and add the img { max-width: 100%; height: auto; } rule once in your stylesheet. Then reload on a slow connection and check that nothing moves.
A few edge cases
- Images whose shape changes on purpose, such as a cropped banner on phones. Use
picture, and give eachsourcethe rightwidthandheight. - User-uploaded images. Store the dimensions when the image is uploaded, and print them in the template. The shape is known at upload time.
- Placeholders. If you show a grey box until the image arrives, make it the same shape.
- Sites that use `object-fit`. The attributes still reserve the space, and
object-fitdecides how the picture fills it.
Check your own page
Run the free audit and look for the unsized images finding. Fix the ones near the top first, because a shift above the content moves more than one below it. Then scroll the page on a slow connection and see whether anything still jumps.
Sources
- The img element on MDN:
widthandheightand how browsers use them to reserve space. - Optimize Cumulative Layout Shift on web.dev: how the aspect ratio is derived from the attributes.
- Performance chapter of the 2025 Web Almanac: how many pages have unsized images.
Start here
Free website audit
Live Google data for any public page: mobile and desktop.
Mobile + desktop · Lighthouse lab test · Real-user Chrome data when Google has it
Rather have this done for you? Speed optimization · Book a call