400 CSS px · ×2slot 400 pxcup-800.jpgcup-crop.jpg400 × 300 · 4:3100vw = 400 px400 × 2 = 800 pxa closer crop1200 CSS px · ×2slot 600 pxcup-1600.jpg600 × 450 · 4:350vw = 600 px600 × 2 = 1200 px1<img src="cup-800.jpg"2 srcset="cup-400.jpg 400w,3 cup-800.jpg 800w,4 cup-1600.jpg 1600w"5 sizes="(max-width: 600px) 100vw,6 50vw"7 width="800" height="600"8 alt="A cup of coffee">400wcup-400.jpg800wcup-800.jpg1600wcup-1600.jpg<picture>src400w800w1600w100vw50vw4:34:3<picture>
Front left: the img tag; behind it, the same picture saved at three widthsBack right: two screens, drawn to scale in CSS pixelsChips: a value travelling from its line to where the browser uses itFront left: one img tag with srcset and sizes. Behind it: the same picture saved 400, 800 and 1600 pixels wide, each tile sized to its pixels. Back right: a phone 400 CSS pixels wide and a laptop 1200 CSS pixels wide, both at 2 device pixels per CSS pixel. Chips carry each value from its line: 100vw gives the phone a 400-pixel slot and it pulls cup-800.jpg; 50vw gives the laptop a 600-pixel slot and it pulls cup-1600.jpg. The picture tile then swaps the phone's image for a closer crop. The two screens are round, made-up examples. To see your own screen's numbers, open the browser console and type innerWidth (CSS pixels across the viewport) or devicePixelRatio.

One file, many screens

  1. An img element shows a picture. With only src, every screen downloads the same file, here cup-800.jpg. But screens differ: a small, plain screen wastes data on pixels it cannot show, and a big, sharp one stretches the picture until it looks soft.

srcset and sizes

The browser picks

Good habits

What happens

;; step 1/11 · one-file
line 1  <img src="cup-800.jpg"
src      one file, for every screen
small    gets more pixels than it can show: wasted data
large    gets fewer than it can show: stretched, soft
fix      offer several sizes and let the browser choose

The HTML standard leaves the final choice to the browser. It may take a smaller file on a slow connection, or reuse a larger one it already has. Browsers aim for the smallest file with enough pixels, as in the figure. sizes is a promise about your CSS. Here the page's CSS would draw the image across the whole screen on narrow viewports and in a half-width column on wider ones, with height: auto keeping its 4:3 shape.