Web & development / CLEARBYTE

Responsive images: srcset, sizes and device pixel ratio explained

srcset lists available image files. With width descriptors, sizes describes the image’s expected display width in CSS pixels, and the browser combines that information with device pixel ratio and its own selection policy. Your CSS still controls the actual layout.

In this guide

An image can look correct while downloading far more pixels than the layout uses. The opposite problem is a small file stretched across a dense screen. Responsive image markup connects the files you generate with the space an image occupies; it is most useful when both sides describe the same layout.

Start with one real component and a few meaningful image sizes. The example here uses a content column capped at 800 CSS pixels with 16-pixel outer gutters on narrow screens. All candidate files show the same composition and have the same 4:3 aspect ratio.

Keep source pixels, CSS pixels and DPR separate

A file that is 800 pixels wide does not have to occupy 800 CSS pixels on the page. A browser can display it in a 400 CSS-pixel slot. At device pixel ratio 2, that slot corresponds to about 800 device pixels across. This is a resolution planning relationship; the browser retains discretion over the resource it chooses.

For the example component, calculate the display slot first: the smaller of 800 pixels and the viewport width minus 32 pixels. Multiply that slot by the DPR to get a useful target source width. Do not multiply the viewport width when the image only occupies a narrow column.

Planning image widths for the example 800-pixel content column
Viewport widthDisplay slot in CSS pixelsDPRTarget source width
3923601360 pixels
3923602720 pixels
10248001800 pixels
102480021600 pixels

Use width descriptors when the layout width changes

The w descriptor states the intrinsic pixel width of a file. It is not a breakpoint and it must describe the actual resource correctly. sizes tells the browser how wide the image is expected to be in the current layout. In the markup below, a viewport of 832 CSS pixels or more uses an 800-pixel slot; narrower viewports use the viewport width minus the two gutters.

The associated CSS is part of the example. If a later design puts this component into a half-width grid, update sizes to match that grid. Leaving sizes at an old full-width value can cause the browser to select a larger resource than the component needs. A correct attribute is an accurate description of the layout, not a collection of popular screen widths.

<img
  src="/images/workspace-800.webp"
  srcset="/images/workspace-400.webp 400w,
          /images/workspace-800.webp 800w,
          /images/workspace-1600.webp 1600w"
  sizes="(min-width: 832px) 800px, calc(100vw - 32px)"
  width="1600" height="1200"
  alt="A desk with a monitor and an open notebook"
  style="display:block;width:calc(100vw - 32px);max-width:800px;height:auto;margin-inline:auto"
>

Predict a candidate, then inspect the actual choice

On the 392-pixel viewport at DPR 2, the example slot is 360 CSS pixels and its target is 720 source pixels. The 800w candidate is a reasonable expected choice from the supplied set. On a wide display at DPR 2, the target is 1600 pixels. These calculations explain the input to resource selection; they are not an instruction that forces a browser to fetch exactly that candidate.

Browsers can account for factors beyond your arithmetic and may retain an already downloaded larger image when the viewport shrinks. For a clean test, open a fresh page context or reload after choosing the device settings, then inspect the selected image URL and transferred bytes in developer tools. Repeatedly resizing one warm page can give misleading conclusions.

A candidate list also creates work for your build process. Generate the actual 400-, 800- and 1600-pixel files, inspect their visual quality and verify that every URL returns an image. Do not rename one 1600-pixel file three times and label the copies with different w values.

  • Check the rendered width of the element rather than assuming it equals the viewport.
  • Compare the selected currentSrc URL with the Network panel’s image response.
  • Inspect file dimensions, response type, cache state and transferred bytes.
  • Repeat at one narrow and one wide viewport, at DPR 1 and DPR 2.
  • Look for horizontal overflow and layout movement before and after image loading.

Choose x descriptors for a truly fixed-size image

A small logo displayed at a fixed width can use density descriptors instead. For an image shown at 120 CSS pixels, supply a 120-pixel file as 1x and a 240-pixel file as 2x. This describes alternative resolutions of the same fixed display size. Do not mix x and w descriptors in one srcset.

Different crops are a separate design problem. If the mobile version needs a close crop of a face while the desktop version shows a wide scene, use picture with suitable source media conditions. That is art direction, whereas this guide’s main example uses the same composition at different resolutions. The alternative text should describe the meaningful content the reader receives.

<img src="/images/mark-120.png"
     srcset="/images/mark-120.png 1x, /images/mark-240.png 2x"
     width="120" height="120" alt="Example project mark">

Keep aspect ratio and loading behavior in the plan

Width and height attributes let the browser reserve space using an aspect ratio before the image arrives. They do not force a responsive image to remain at those CSS dimensions when your stylesheet changes its width. In the 4:3 example, an 800-pixel display width gives a 600-pixel display height; at 360 pixels wide, the proportional height is 270 pixels.

Lazy loading is useful for images farther down a long page, but the important image a reader sees immediately should not have its request delayed indiscriminately. Decide based on where the component is used. Responsive candidates reduce excess pixels; suitable compression, file format and an appropriate loading strategy address different parts of the loading cost.

Raw image memory and network file size are also different quantities. A compressed WebP file can be small on the network while decoding to a much larger pixel buffer. Use the image-memory calculator for the decoded dimensions, then measure the actual compressed file rather than predicting its bytes from pixel count alone.

A release checklist for a responsive image component

Treat the component’s layout rule and image generation rule as one small contract. Keep the candidate widths, crop, aspect ratio, quality setting and sizes expression with the component so a future layout change can update them together. A maximum-width change from 800 to 1000 pixels should trigger another candidate review.

Before publishing, check the fallback src, all srcset URLs, meaningful alternative text and the image’s reserved space. Use the CSS-to-device-pixel calculator to reproduce the table with your own slot and DPR. Use the aspect-ratio calculator when creating the corresponding heights. The useful result is a component whose files and layout agree across real devices.

Common questions

Does sizes change the CSS width of my image?

No. It describes the expected display slot for resource selection when using width descriptors. CSS controls the rendered layout, so the two descriptions need to agree.

Why did the browser keep a large image after I made the window smaller?

The browser may reuse an image it already has. Test a fresh load with the desired viewport and DPR, then inspect the selected resource and network transfer rather than relying on one resize sequence.

Is a 2x image always twice the file size?

No. Doubling both dimensions gives four times as many pixels, but encoded bytes also depend on image content, format and compression quality. Measure the generated files.

Sources & definitions

Method checked: