Reputation: 28534
I have been into CSS for quite a while now, but srcset
and sizes
for the image element confuse me. Here is an example that I thought would work.
<img alt="Background image flowers"
srcset="img/flowers-480.jpg 480w,
img/[email protected] 480w 2x,
img/flowers-768.jpg 768w,
img/[email protected] 768w 2x,
img/flowers-960.jpg 960w,
img/[email protected] 960w 2x,
img/flowers-1280.jpg 1280w,
img/[email protected] 1280w 2x"
sizes="(max-width: 1279px) 100vw,
(min-width: 1280) 1280px"
src="img/flowers-960.jpg">
The idea is to have an image that's 100% of the viewport until the viewport is 1280px wide or wider, then the image will be fixed size. However, to compensate for higher DPI devices I thought it was recommended to add DPI descriptors (1.5x, 2x and so on), as suggested here and here.
What I thought the above code would do is:
However, when I put this through a validator I get the following error:
Error: Bad value for attribute srcset on element img: Width for image
img/[email protected]
is identical to width for imageimg/flowers-480.jpg
So clearly I am completely missing the point of how srcset and sizes work. What am I doing wrong?
Upvotes: 6
Views: 5043
Reputation: 7899
As of 2022, I'd argue it's just easier to assume high DPI screens and leverage the breakpoint idea of srcset
:
<img alt="Background image flowers"
srcset="img/flowers-480.jpg 480w,
img/flowers-768.jpg 768w,
img/flowers-960.jpg 960w,
img/flowers-1280.jpg 1280w,
img/flowers-1920.jpg 1920w,
img/flowers-4096.jpg 4096w"
sizes="(max-width: 1279px) 100vw,
(min-width: 1280) 1280px"
src="img/flowers-960.jpg">
Upvotes: 1
Reputation: 951
The "art direction use case", linked in @vbarinov's answer, quoted from developers.google.com, shows how to combine both width and pixel density as criteria for which image source to load and display:
<picture>
<source media="(min-width: 800px)" srcset="head.jpg, head-2x.jpg 2x">
<source media="(min-width: 450px)" srcset="head-small.jpg, head-small-2x.jpg 2x">
<img src="head-fb.jpg" srcset="head-fb-2x.jpg 2x" alt="a head carved out of wood">
</picture>
In viewports that are at least 800 pixels wide, head.jpg
should be displayed on a single density display, while head-2x.jpg
should be displayed on a display with double or greater density.
Viewports below 800 pixels with, but at least 450 pixels wide, single-density displays should show head-small.jpg
, while head-small-2x.jpg
is for double density or greater.
The fallback image definition inside the <img>
tag has another srcset
that defines a double-density version (head-fb-2x.jpg
) for viewports below 450 pixels width.
Single-density devices and browsers that don't support source sets or picture elements will fall back to display head-fb.jpg
.
In a more complex scenario, we can also add alternative image formats, to take advantage of webp
compression while providing jpg
versions for browsers without webp
support.
<picture>
<source media="(min-width: 800px)" srcset="head.webp, head-2x.webp 2x" with="800" height="941">
<source media="(min-width: 800px)" srcset="head.jpg, head-2x.jpg 2x" with="800" height="941">
<source media="(min-width: 450px)" srcset="head-small.webp, head-small-2x.webp 2x" width="800" height="941">
<source media="(min-width: 450px)" srcset="head-small.jpg, head-small-2x.jpg 2x" width="800" height="941">
<img src="head-fb.jpg" srcset="head-fb-2x.jpg 2x" width="400" height="471" alt="a head carved out of wood">
</picture>
Here is a codepen of the complex example.
Upvotes: 8
Reputation: 403
According to MDN, "It is incorrect to mix width descriptors and pixel density descriptors in the same srcset attribute. Duplicate descriptors (for instance, two sources in the same srcset which are both described with '2x') are invalid, too."
You have 2x
listed 4 times. That's invalid.
Here is an example from MDN:
Example 4: Using the srcset
and sizes
attributes
The src
attribute is ignored in user agents that support srcset
when using 'w' descriptors. When the (max-width: 600px)
media condition matches, the image will be 200px wide, otherwise it will be 50vw wide (50% of the viewport width).
<img src="clock-demo-thumb-200.png"
alt="Clock"
srcset="clock-demo-thumb-200.png 200w,
clock-demo-thumb-400.png 400w"
sizes="(max-width: 600px) 200px, 50vw">
Upvotes: 2
Reputation: 521
For a combination of HPDI settings and responsive sizes for images you should actually use <picture>
with a few <source>
and a fallback <img>
elements.
Details are in this article.
Upvotes: 2
Reputation: 46361
As defined on MDN for <img srcset="...">
:
Each string is composed of:
a URL to an image, optionally, whitespace followed by one of:
- a width descriptor, or a positive integer directly followed by '
w
'. The width descriptor is divided by the source size given in thesizes
attribute to calculate the effective pixel density.- a pixel density descriptor, which is a positive floating point number directly followed by '
x
'.
You tried to use both, and that's illegal.
Upvotes: 4