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.