Image with srcset and sizes attribute

  1. Match order
    1. Fallback
  2. Rounding
  3. CSS pixels, device pixels and pixel density
  4. Art direction?
  5. Image element width
  6. Worked example
A test responsive image
<img alt="A test responsive image"
     src="fallback.png"
     srcset="300x300.png 300w,
             600x600.png 600w,
             1200x1200.png 1200w,
             1500x1500.png 1500w"
     sizes="(min-width: 1500px) 1500px,
            (min-width: 1200px) 1200px,
            (min-width: 600px) 600px,
            (min-width: 300px) 300px,
            300px" />
			

When using the sizes attributes you are able to specify the size an image will be (in CSS pixels) when used on the page in different scenarios. You do this by defining <media-condition> <image-size> in sizes. The intention is you as the author know exactly how an image will be used, and if you know that an image will only be 300px or 33vw wide in certain cases, you can tell the browser this. The browser can then choose to download a smaller image from srcset than it would have otherwise. Because if you don't tell it how big the image will be, it assumes worst case scenario, that the image will be the full width of the viewport.

Match order

The statements in sizes are read first to last, and the first matching one will one. This means order is important depending on how you write your media conditions.

Fallback

The final entry in sizes doesn't have a condition, it's just a source size value. It is a fallback and is used if none of the media conditions match.

Rounding

If no image in srcset has a width descriptor that exactly matches an image then generally the browser will round up to the next largest. This essentially errs on ensuring the image always looks good vs. choosing the smallest image.

CSS pixels, device pixels and pixel density

Note the following about different parts of srcset and sizes:

When going from the sizes source size descriptor to find the matching srcset width descriptor a conversion happens between CSS pixels and device pixels. This conversion takes the pixel density/device pixel ratio into account. See the worked example below for more details.

Art direction?

It might seem like you could use the media conditions in sizes to control art direction. For example, you might specify that on devices that were less than 300px you use a square image, but on devices that are larger than this you'll use a rectangular image. This won't work for two reasons:

If you want art direction, the solution is to use the <picture> element.

Image element width

When srcset is used with sizes the width of the image element on the page is set according to the source size descriptor of the matching sizes entry. E.g. if the entry (min-width: 600px) 600px matches, the image will be 600 CSS pixels wide. Note this will apply regardless of the actual size of the source image, as the browser essentially trusts you've given it correct information in the sizes attribute, so won't override that even if the actual image has a different size, it essentially replaces the intrinsic dimensions of the image.

Worked example

Above is an example image using srcset and sizes. Described here are the steps taken by the browser to work out the final image to display, in this example for an iPhone 11 in portrait orientation.

  1. Work out the entry from sizes that matches:
    1. The width of an iPhone 11 in CSS pixels is 414.
    2. Going down the sizes list from the top, the first condition to match is min-width: 300px.
    3. This has a source size value (the right-hand size) of 300px which is the desired width of the image in CSS pixels.
  2. Work out that entry from srcset that matches:
    1. First work out what the desired image size in device pixels. We do this by multiplying the source size value we just worked out by the device's pixel density, which for iPhone 11 is 2. In this case that's: 300px (CSS pixels) * 2 (pixel density) = 600px (device pixels)
    2. The srcset attribute is then consulted to find the closest matching image. In this case there is a width descriptor of 600w which matches 600px exactly. This results in the corresponding 600x600.png image being chosen.