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>Exercise: RWD Images
What does applying max-width: 100% to an image primarily achieve?