For developers

Responsive Images Explained: srcset, sizes and the <picture> Element

How websites serve a different image size to every screen, how srcset and sizes work, when to use the picture element, and the common mistakes that waste bandwidth.

A phone with a 400-pixel-wide screen doesn't need the same 2,400-pixel photo as a large desktop monitor. Sending it anyway wastes data and slows the page. Responsive images solve this: the page offers several versions of the same picture and the browser downloads only the one that fits. This guide explains how that works and how to do it well.

The problem with a single src

With a plain <img src="photo.jpg">, every visitor downloads the same file. If it's sharp on a 27-inch screen, it's several times too large for most phones. If it's small enough for phones, it looks blurry on big and high-density (“retina”) screens. There is no single right size.

srcset with density descriptors (1x, 2x)

For images shown at a fixed size, such as a logo or an avatar, offer versions for normal and high-density screens:

<img src="logo-200.png" srcset="logo-200.png 1x, logo-400.png 2x" width="200" height="60" alt="Company logo">

A standard screen picks the 1x file; a phone or laptop with a 2x display picks the sharper one. The src is a fallback for very old browsers.

srcset with width descriptors and sizes

For images whose displayed size changes with the screen, such as a full-width banner or an article photo, list the files with their real pixel widths, and tell the browser how wide the image will appear:

<img
  src="hero-1200.jpg"
  srcset="hero-480.jpg 480w, hero-800.jpg 800w,
          hero-1200.jpg 1200w, hero-1800.jpg 1800w"
  sizes="(max-width: 700px) 100vw, 700px"
  width="1200" height="675" alt="Mountains at sunrise">

Read sizes as: “on screens up to 700 px wide, the image fills the whole width (100vw); otherwise it's 700 px wide.” The browser multiplies that width by the screen's pixel density and picks the smallest file that is big enough. A phone 390 px wide at 3x density needs about 1,170 pixels, so it chooses hero-1200.jpg.

The w number must be the file's actual width in pixels. If you write 800w for a file that is really 1,600 px wide, the browser's calculation goes wrong.

The <picture> element

<picture> is for two jobs that srcset alone can't do.

1. Offering modern formats with a fallback

<picture>
  <source type="image/avif" srcset="photo.avif">
  <source type="image/webp" srcset="photo.webp">
  <img src="photo.jpg" width="1200" height="800" alt="...">
</picture>

The browser uses the first format it supports. See JPEG vs PNG vs WebP vs AVIF for how much each format saves.

2. Art direction

Sometimes a wide landscape crop doesn't work on a narrow phone. With <source media="(max-width: 600px)" srcset="hero-portrait.jpg"> you can serve a differently cropped image, not just a smaller one.

Common mistakes

  • Missing sizes. With width descriptors but no sizes, the browser assumes the image is the full screen width and often downloads a file far too large.
  • Missing width and height. Without them the page jumps around as images load, which hurts Cumulative Layout Shift (CLS). Always set them; CSS can still make the image fluid.
  • Too many or too few versions. Four to six widths, roughly 1.5× apart, are usually enough.
  • Lazy-loading the main image. The first large image people see should load immediately. See our lazy loading guide.

What this means when you save images

Because of srcset, the image you right-click is often not the largest version available. The other sizes are listed in the page's HTML. Our extractor reads srcset and <picture> sources and lists every version separately, so you can pick the highest-resolution file. On many content management systems, the file names even contain the width (for example -1024x683.jpg), which makes the largest one easy to spot.

Quick checklist

  1. Fixed-size image? Use 1x, 2x descriptors.
  2. Fluid image? Use w descriptors and an accurate sizes.
  3. Want AVIF/WebP? Wrap it in <picture> with a JPEG fallback.
  4. Always include width, height and meaningful alt text.
  5. Test in developer tools: the Network tab shows which file each screen size actually downloads.