Reference guide · images · Published 2026-08-16 · 4 min read

How browsers pick a srcset image

How browsers pick srcset images with w descriptors and sizes: the density math, the first-fit rule, and the mismatch traps that cause big downloads.

The three inputs the browser uses

A browser's srcset picker needs three numbers, and it derives the answer from them:

  1. The candidate list: every w descriptor in the srcset (e.g. photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w).
  2. The rendered width: the sizes attribute at the current viewport (e.g. sizes="(min-width: 800px) 50vw, 100vw"). This is the width in CSS pixels that the <img> will occupy in the layout.
  3. The device pixel ratio (DPR): 1 for a normal screen, 2 for most phones, 3 for a high-end phone.

The two-step algorithm

The choice happens in two steps, and the second one surprises people.

Step 1, scale the wanted width by DPR. Compute wantedWidth = renderedWidth * DPR. A 50vw rendered image on a 750px viewport with a 2x phone wants 375 * 2 = 750 effective pixels.

Step 2, pick the smallest candidate whose intrinsic width is at least the wanted width. The browser walks the list from smallest to largest and takes the first descriptor where candidateW >= wantedWidth. Only when none fits does it pick the largest. This is the "minimum viable candidate" rule, not "closest to the target", which surprises most people.

For the classic example:

<img srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
     sizes="(min-width: 800px) 50vw, 100vw"
     alt="...">

The rule is deliberate: the browser always errs toward the smallest file that cannot look worse than the CSS size, which keeps bytes low and sharpness guaranteed. The sizes attribute article explains why an absent or wrong sizes default to 100vw breaks the whole math.

The DPR twist

The most common mismatch "why is my 400w file not chosen on mobile" comes from ignoring DPR. A 360px-wide phone at DPR 3 computes 360 * 3 = 1080, so it needs a file of 1080w, and your smallest candidate is 400w. The browser walks to 1200w. If you see huge files on phones, check the DPR factor before blaming sizes: the fix is more candidates or a realistic DPR-aware pipeline, not a lower sizes.

The overlap on src and the fallback

When no candidate matches (for example, an old browser that does not parse srcset), the browser uses src with the sizes ignored. Keep src pointing at a good middle file. Also note: the browser prefetches with the network priority order and the intersection of candidates it knows; a LCP image should be the fetchpriority="high" one, covered in the LCP article.

Verify the choice

In DevTools, the Network tab shows the exact URL requested with the ? query timestamp. Compare against your manual math:

  1. Set the device emulation DPR explicitly.
  2. Note the rendered width from the layout overlay.
  3. Compute wantedWidth = rendered * DPR.
  4. Confirm the smallest candidate >= that number was fetched.

A mismatch almost always means sizes does not match the CSS layout width (a common cause of downloading a 1200px file for a 150px avatar) or the candidate list misses the desired size. The gap between the largest candidate and the rendered size is where the browser quietly picks a candidate you never anticipated, which shows up as an unexpectedly large download in the Network view.

What the DPR skew means for your files

The sibling articles cover the rest of the responsive-image stack: the srcset basics, the sizes attribute, and the optimisation guide for the pipeline that produces the candidates.

Need a website built, fixed, optimised, migrated or replaced?

This technical resource is written by CSMBAC, a small design and development studio. If you would rather hand the problem to a professional, the website service page explains how we build enquiry-ready websites.

Explore website services