width, height & Layout Shift

Two numeric attributes on `<img>` tell the browser how much space to hold open before the image loads. Without them, every image that loads shifts the text around it.

HTML5 min readConcept 18 of 42

What they are

The width and height attributes on <img> describe the intrinsic dimensions of the image in CSS pixels. They are not the same as a CSS width or height style: the attributes describe the image's natural size, and the browser uses them to compute an aspect ratio before the image bytes have arrived.

Cumulative Layout Shift (CLS) is a Core Web Vital that measures how much page content moves unexpectedly after the initial render. Images without width and height are the single most common cause of a bad CLS score, because the browser allocates zero height for the image slot and then shoves everything below the image downward when the file finishes loading.

Why it matters

A page that shifts while the user is reading is uncomfortable and error-prone. A user who is about to tap a button and the page jumps may tap the wrong thing. Google's CLS metric captures exactly this: cumulative unexpected movement during the page load window. A score above 0.1 is considered poor, and a page full of sizeless images can easily hit 0.5 or higher.

Setting width and height is a one-attribute fix per image that eliminates the most common source of CLS entirely. The browser reads the two numbers, divides them to get the aspect ratio, and reserves that slot in the layout immediately. By the time the image loads, the slot is already the right size and nothing moves.

How it works

Set width and height to the image's actual pixel dimensions: <img src="photo.jpg" alt="..." width="800" height="600">. These values do not have to match the CSS display size. What matters is that they reflect the correct aspect ratio of the image.

Modern browsers (since 2019) derive a default aspect-ratio: 800 / 600 from the attributes and apply it automatically. This means you can still use CSS width: 100%; height: auto to make the image responsive, and the browser will maintain the ratio from the HTML attributes, reserving the right amount of vertical space at every viewport width. The attributes and the CSS cooperate rather than conflict.

For <video> elements the same rule applies: add width and height attributes to prevent layout shift as the video metadata loads. For images served at different sizes through srcset (concept #19), set width and height to the dimensions of the default src image.

Try it

See the difference between an image slot with no dimensions reserved versus one where the browser has held the correct space open from the start.

<!-- no dimensions: CLS risk -->
<img src="photo.jpg"
alt="Coastal path" />
<!-- with dimensions: stable -->
<img src="photo.jpg"
alt="Coastal path"
width="800"
height="400" />

no width / height

Read the coastal path guide...

browser allocates 0 px; text sits here before load

Read the coastal path guide...

after load: text jumps down (CLS)

width="800" height="400"

Read the coastal path guide...

browser reserves the right space; text never moves

Same image: one shifts the page on load, one holds its space open.

Check yourself

Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.

  1. 1An image loads and the paragraph below it jumps down. What caused that?
  2. 2An <img> has width="1200" height="800" and CSS width: 100%; height: auto. What does the browser render?
  3. 3The original image is 2400x1600px but you display it at 800x533px with CSS. What do you put in the attributes?

Remember this

  • Always set width and height on <img> to the image's intrinsic pixel dimensions to prevent layout shift.
  • Browsers derive aspect-ratio from the attributes; width: 100%; height: auto in CSS then maintains that ratio responsively.
  • Missing dimensions = zero height reserved = content below shifts when the image loads (CLS).
  • The attributes describe the natural image size; CSS controls the display size. Both can coexist without conflict.

Done with this concept?

Mark it complete to track your progress. No login needed.