Responsive Images
`srcset` offers the browser a menu of image files at different sizes. `sizes` tells it how big the image will display. Together they let the browser serve the smallest file that still looks sharp.
What they are
srcset is an attribute on <img> that lists multiple image files with size descriptors. Width descriptors (480w, 1200w) describe each file's intrinsic width in pixels. The browser reads the list, consults the sizes attribute to find out how wide the image will actually display, factors in the screen's pixel density, and downloads the smallest file that still covers the display need.
sizes is a media-condition list that maps viewport widths to display widths: sizes="(max-width: 640px) 100vw, 50vw" tells the browser the image fills the full viewport on small screens and half of it on larger ones. Without sizes, the browser assumes the image is always 100vw wide, which causes it to download unnecessarily large files when the image only occupies part of the layout.
Why it matters
A single image served at full desktop resolution to a mobile phone wastes the user's bandwidth and slows the page. A single image sized for mobile served to a 4K monitor looks blurry. srcset solves both: phones download the small file, desktops download the large one, and the browser makes the decision automatically based on the available information.
Device pixel ratio compounds the problem. A modern phone with a 2x display needs an image twice as wide as its CSS pixel count to look sharp. srcset with width descriptors accounts for this automatically: a phone that displays the image at 400 CSS pixels and has a 2x display will look for a source at least 800px wide.
How it works
List files from smallest to largest in srcset with their intrinsic widths. Write sizes to match your layout: if the image is full-width on mobile but sits in a 50% column on desktop, write sizes="(max-width: 768px) 100vw, 50vw". Always include a plain src as the fallback for browsers that do not support srcset.
For pixel density only (no responsive layout): use x descriptors instead of w. srcset="photo.jpg 1x, photo@2x.jpg 2x" serves the 2x image to Retina screens and the 1x to standard screens. This is simpler but does not help with different image sizes in different layouts.
Use <picture> when you need different image crops for different viewports (art direction), or when you want to serve a modern format like WebP or AVIF with a JPEG fallback. The browser tries each <source> in order and picks the first one whose media condition or type it supports. The <img> inside <picture> is the required fallback.
Try it
Select a viewport size and watch the browser choose a different source from the srcset. Notice how device pixel ratio multiplies the display need.
Viewport 768px: browser picks hero-800.jpg
Check yourself
Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.
Remember this
srcsetwithwdescriptors lists source files by intrinsic width; the browser picks the best fit based on display need and DPR.sizestells the browser the CSS display width of the image at each viewport; without it, the browser assumes100vw.- Always include a plain
srcfallback for browsers that do not supportsrcset. - Use
<picture>for art direction (different crops) or format switching (WebP/AVIF fallbacks), not just more size variants.
Done with this concept?
Mark it complete to track your progress. No login needed.