Guides/ Images
devices

Responsive Images in HTML: srcset, sizes & picture

Serving a 1200px image to a 400px mobile screen wastes 3–5x more bandwidth than necessary. HTML's srcset, sizes, and picture attributes solve this without any JavaScript — the browser picks the optimal image for each device automatically.

April 2026 · 9 min read

srcset: Multiple Image Sources

The srcset attribute provides a list of image sources with their intrinsic widths. The browser chooses the best one based on the current viewport width and device pixel ratio.


Hero image

sizes: Tell the Browser the Display Size

The sizes attribute describes how wide the image will actually be displayed. The browser uses this — combined with viewport width — to select the most appropriate srcset source.


Photo description

picture: Art Direction & Format Switching

The picture element wraps multiple source elements, each with srcset. The browser uses the first matching source. Use it for art direction (different crops per breakpoint) or format switching (AVIF → WebP → JPEG).



  
  
  

  
  

  
  Hero




  
  
  Photo

Device Pixel Ratio Descriptors

For fixed-size images (like icons, avatars, product thumbnails), use the x descriptor instead of w+sizes. It's simpler when the display size is always the same.


User avatar


Company logo

Common Responsive Image Mistakes

  • Omitting the fallback src — the src attribute on img is required as fallback for browsers that don't support srcset (rare in 2026, but also used as the default in picture elements).
  • Not specifying width and height — missing dimensions cause CLS (Cumulative Layout Shift) as the page reflows when the image loads. Always set width/height equal to the intrinsic dimensions of the source image.
  • Lazy-loading hero/LCP images — hero images (the Largest Contentful Paint element) should never have loading='lazy'. Lazy loading delays them, worsening LCP. Only lazy-load below-the-fold images.
  • Generating too many srcset sizes — you don't need an image for every 50px increment. 3–4 breakpoint sizes (e.g., 400, 800, 1200, 2400) cover most cases efficiently.
  • Using vw in sizes without calc for padding — if your container has 16px padding on each side, the image isn't truly 100vw — it's calc(100vw - 32px). This matters for accurate browser selection.

Frequently Asked Questions

Does the browser always pick the smallest image in srcset?
No — the browser picks the smallest source that meets the quality requirements for the current display size and pixel density. It may also factor in connection speed on mobile (it can pick a smaller image on slow connections even if a larger one would technically fit).
Should I use srcset or picture?
Use srcset+sizes for most responsive images (same content, different sizes). Use picture when you need art direction (different crops) or format fallbacks (AVIF/WebP/JPEG). For format fallbacks specifically, picture is the only way.
What is preload and when should I use it for images?
Use for your LCP hero image — this tells the browser to fetch it before it parses the img tag in the body. For responsive images, use imagesrcset and imagesizes attributes on the preload link to preload the correct breakpoint variant.
How many srcset sizes should I generate?
For most images: 400w, 800w, 1200w, and 2400w. This covers mobile (400), tablet (800), desktop 1x (1200), and desktop 2x Retina (2400). For full-bleed hero images, add 3200w for very large screens.