srcset and sizes attribute
<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.
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.
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.
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.
Note the following about different parts of srcset and sizes:
sizes the media condition and the source size descriptor of each entry are both in CSS pixels.
srcset the width descriptor is in device pixels.
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.
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:
srcset values are only suggestions. The browser can decide to download a different image than
the one that might have matched exactly, for example it might download a smaller image if network conditions
are poor.
If you want art direction, the solution is to use the
<picture> element.
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.
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.
sizes that matches:
sizes list from the top, the first condition to match is
min-width: 300px.
300px which is the desired width
of the image in CSS pixels.
srcset that matches:
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.