Responsive images

HTML · Practical · 12 min

Sending a 3000-pixel image to a phone wastes bandwidth and slows the page more than almost anything else.

One image file can't suit both a phone and a 4K monitor. HTML lets you offer several and let the browser choose.

Resolution switching with srcset and sizes: list candidate files with their intrinsic widths (photo-480.jpg 480w, photo-1200.jpg 1200w), and tell the browser how wide the image will be displayed with sizes, a list of media conditions and lengths like (max-width: 600px) 100vw, 50vw. The browser multiplies that width by the device pixel ratio and downloads the smallest adequate file. It needs sizes because it picks the image before CSS layout is known. Without sizes it assumes 100vw.

For fixed-size images, such as an 80px avatar, use density descriptors instead: srcset="a.jpg 1x, a@2x.jpg 2x".

The picture element handles two other cases:

  • Format switching: <source type="image/avif"> and <source type="image/webp"> before the fallback <img>; the browser takes the first type it supports.
  • Art direction: <source media="(max-width: 600px)" srcset="crop-tall.jpg"> serves a different crop on narrow screens.

The <img> inside <picture> is required: it's what actually renders, and it carries alt, width, height and loading. The <source> elements only supply alternative URLs.

Example

<!-- Resolution switching: browser picks by display width x pixel density -->
<img src="hero-1200.jpg"
     srcset="hero-480.jpg 480w, hero-800.jpg 800w, hero-1200.jpg 1200w, hero-2000.jpg 2000w"
     sizes="(max-width: 700px) 100vw, 700px"
     alt="Mountain lake at sunrise" width="1200" height="675">

<!-- Fixed-size image: density descriptors -->
<img src="avatar.jpg" srcset="avatar.jpg 1x, avatar@2x.jpg 2x"
     alt="Ada Lovelace" width="80" height="80">

<!-- Modern formats with a fallback, plus a tall crop for phones -->
<picture>
  <source type="image/avif" srcset="product.avif">
  <source type="image/webp" srcset="product.webp">
  <source media="(max-width: 600px)" srcset="product-tall.jpg">
  <img src="product.jpg" alt="Blue running shoe" width="1000" height="600">
</picture>

Remember

  • srcset with w descriptors + sizes = browser picks the right resolution
  • Use 1x/2x descriptors for fixed-size images
  • picture + source switches formats or crops; the inner img still renders

Watch out for

  • Leaving out sizes with w descriptors, so the browser assumes 100vw and downloads files that are too big.

Check yourself

  1. Why does the browser need the sizes attribute with srcset width descriptors?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: developer.mozilla.org/en-US/docs/Web/HTML/Guides/Responsive_images