Reference guide · images · Published 2026-08-16 · 4 min read
Serving images for retina and high-DPI displays
Serve sharp images on retina and high-DPI displays with srcset density descriptors, and verify the browser picks the right file.
- ·Why density matters
- ·The x descriptor
- ·Verify the pick
Nearly all modern phones and many laptops use high-DPI (retina class) screens that pack two or three physical pixels into each CSS pixel. A 400 CSS-pixel-wide image rendered at 800 physical pixels looks soft unless the supplied file has enough pixels. The srcset density descriptor, the x descriptor, is the simplest way to hand the browser a higher-resolution copy for exactly those screens.
How density works
A CSS pixel is a logical unit. On a standard screen one physical pixel fills it; on a devicePixelRatio of 2, four physical pixels (2 by 2) fill one CSS pixel. If you render a 200 pixel wide image element but the high-DPI screen needs 400 physical pixels, the best the browser can do is stretch the 200 pixel file and blur it.
The requirement is therefore resolution, not file extension tricks. To look sharp on a DPR 2 screen, supply a file at roughly twice the rendered width.
The x descriptor
Where you know a fixed rendered width, express the choice in multiples of it:
<img src="logo-200.png" srcset="logo-400.png 2x, logo-600.png 3x" alt="Company logo">
The 1x file is the baseline in src, and 2x and 3x are optional higher-density copies. The browser picks the one that matches its device pixel ratio, and a DPR 2 phone gets logo-400.png.
The x descriptor is best when the image has a fixed rendered width, such as a logo or a thumbnail. When the render width varies with the viewport, prefer the w descriptor plus sizes so the browser also accounts for how wide the image will be; that is the responsive srcset pattern. The sizes attribute article explains the width model in detail.
Why 2x and not more
Beyond 2x the visual gain shrinks fast. A 3x file is roughly 2.25 times the pixels of a 2x file for a marginal perceived improvement, mostly relevant to very high-density screens such as some Androids and MacBook Pro displays when an image renders small. A practical policy:
| Rendered width | Files to provide |
|---|---|
| Small asset (logo, icon) | 1x, 2x, 3x |
| Content photo | 1x and 2x, with responsive widths |
| Background or hero | Width-tuned, not just density |
Always provide dimensions on the image so the layout reserves the correct space and avoids shift (see aspect ratio). Density does not change the layout box; it changes the internal detail.
Verify the pick
A common mistake is shipping a 2x file that is no larger than the 1x file, so dense screens gain nothing. Verify in dev tools:
- Open the Network tab and set the device toolbar to a DPR 2 profile, for example an iPhone preset.
- Confirm the requested image is the 2x or 3x candidate, not the 1x fallback.
- Compare the reported transfer size against the file's intrinsic dimensions.
- Repeat at DPR 1 to confirm a standard screen fetches only the small file.
If the same size is downloaded on every profile, either the descriptors are mislabelled or the candidates are actually identical files. Fix the source set, then re-test.
Balance sharpness and weight
A 2x photo is about four times the bytes of the 1x version on lossy formats at the same quality, so density multiplies weight fast. Compress each variant independently (the compression guide sets the budget) and rely on the browser's choice so low and high density devices both pay only for what they need. The picking algorithm article walks through how a browser lands on a candidate when widths and densities are combined.