RWD Picture Element and Srcset

srcset and the <picture> element let the browser pick which image file to download based on screen size, pixel density, or format -- solving the bandwidth problem that max-width alone can't.

Two Different Problems, One Confusing Pair of Tools

Responsive images actually cover two separate needs that often get lumped together. Resolution switching means serving the same picture at different file sizes so a phone doesn't download a desktop-sized file -- that's what srcset and sizes are for. Art direction means swapping in a genuinely different image (a different crop, or a different photo entirely) depending on screen size -- that's what the <picture> element is for.

Resolution Switching With srcset

The srcset attribute lists several versions of the same image, each labeled with its actual pixel width using a w descriptor. The sizes attribute then tells the browser how wide the image will actually be drawn at different viewport widths, so it can work out which candidate file is the smallest one that will still look sharp -- before it downloads anything.

srcset With Width Descriptors

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>

<img
  src="veggies-800.jpg"
  srcset="veggies-400.jpg 400w,
          veggies-800.jpg 800w,
          veggies-1200.jpg 1200w"
  sizes="(max-width: 600px) 100vw,
         (max-width: 1000px) 50vw,
         33vw"
  alt="Harvested vegetables in a wooden crate">

</body>
</html>
  • "(max-width: 600px) 100vw" -- on screens 600px or narrower, the image is drawn at the full viewport width.
  • "(max-width: 1000px) 50vw" -- on screens up to 1000px wide, it's drawn at about half the viewport width.
  • "33vw" -- the fallback for anything wider: roughly a third of the viewport.
  • The browser combines these hints with its own screen width and pixel density to request the smallest candidate file that will still look sharp -- it may pick a smaller file on a narrow phone and a larger one on a high-density retina laptop, even at the same CSS width.

Art Direction With <picture>

Sometimes scaling the same photo isn't enough -- a wide banner shot that looks great on a desktop hero section turns into an unreadable sliver when squeezed onto a phone, and what you actually want is a tighter, taller crop instead. The <picture> element wraps a list of <source> elements, each with its own media condition, and the browser evaluates them top to bottom and uses the first one that matches. A closing <img> is required, both as the fallback for browsers that don't understand <picture> and as the element that actually renders whichever source wins.

Art-Directed picture

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>

<picture>
  <source media="(max-width: 600px)" srcset="hero-portrait.jpg">
  <source media="(max-width: 1200px)" srcset="hero-square.jpg">
  <img src="hero-wide.jpg" alt="Team collaborating around a whiteboard">
</picture>

</body>
</html>

Format Fallback With type

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>

<picture>
  <source srcset="photo.avif" type="image/avif">
  <source srcset="photo.webp" type="image/webp">
  <img src="photo.jpg" alt="Sliced citrus fruit on a marble counter">
</picture>

</body>
</html>
Note: A <source> can also switch on type instead of media, letting you offer a smaller modern format like AVIF or WebP first and fall back to a universally supported JPEG -- the browser silently skips any source whose format it can't decode. You can even combine srcset and sizes on the final <img> inside a <picture>, giving you art direction and resolution switching at the same time.

Exercise: RWD Images

What does applying max-width: 100% to an image primarily achieve?