9

I have read through a number of articles on using srcset for both device-pixel-density adjustments as well as art direction:

The State of Responsive Images in 2015 by Paddi Macdonnell

srcset Part 2: The W descriptor and sizes attribute by Rich Finelli

Neither of these makes it clear whether w-descriptors can be used without the sizes attribute. Most indicate the contrary (w-descriptor work together with sizes)

My own rudimentary testing confirms that image switching does work using only w descriptors.

I have found that when a number of different images are specified according to their width using the w-descriptor, the browser will choose the best image that will fit within a confined space.

No other code is necessary.

This is obviously confusing when designing responsive sites because, I as a designer only need the following cases:

  1. Change the image based on the device-pixel-density (Works for me. Great!)
  2. Change the image (art-direction) based on the available width (Works for me. Great!)

I am wondering how the sizes would factor into this debacle. I do wholly appreciate that this is a new-ish feature.

HubCap
  • 323
  • 5
  • 14

2 Answers2

11

sizes isn't strictly required, but if you don't use it, those w descriptors will resolve against the default values of sizes, which is 100vw. In other words, omitting sizes is equivalent to specifying sizes=100vw, which implies that the image is intended to be rendered at the full screen width. If this is what you intend, great, feel free to omit it, tho specifying it (to make your intent clear) is probably better.

But if you intended anything else, like the example in ausi's answer where the element it set to 200px, then you better specify sizes or else you'll get bad results.

I haven't read the tutorials you're linking to, but just in case they didn't make this clear: the algorithm for deciding what source to download is based on the pixel density, as expressed by the x descriptor. The w descriptor is converted into an equivalent x descriptor by dividing its value by the appropriate sizes value. They exist solely because sometimes you don't know the final laid-out size of the image in pixels at authoring time. If you do know the final size, using x is probably easier.

(Tho it wasn't designed for this purpose, you can also use w even if you do know the laid-out size if you just want to avoid doing the math to figure out the x descriptors. Just listing the source widths and the laid-out width and letting the browser figure things out can be easier in some cases. However, if you know the laid-out width, you should be designing for it explicitly so your ratios are simple integers anyway - it's much better to send a 1x or 2x image than it is to send to .9x image and have the browser scale it up.)

Xanthir
  • 18,065
  • 2
  • 31
  • 32
  • 4
    The `sizes` attribute IS strictly required if there is a `srcset` attribute with a width descriptor. From the spec: "If the srcset attribute has any image candidate strings using a width descriptor, the sizes attribute must also be present". See https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element – Nicolas Hoizey Mar 24 '17 at 09:40
  • @NicolasHoizey no, it's not required. Not in the sense that the browser would completely error out if it's absent (it won't). [The HTML Standard](https://html.spec.whatwg.org/multipage/images.html#parsing-a-sizes-attribute) specifically says _"or the empty string, if the attribute is absent"_ and then goes on to say _"If the above algorithm exhausts unparsed sizes list without returning a size value, then return `100vw`"_. So Xanthir is correct. Omitting `sizes` attribute is the same as saying `sizes="100vw"`. (To be clear, yes it is required by standard, but there's a fallback if missing.) – ADTC Sep 25 '21 at 13:45
  • @ADTC you're right, browsers behave "fine" in absence of `sizes`, as they do with many other HTML tags or attributes. I was refering to the requirement in the standard only. I'm maybe old fashioned. ‍♂️ – Nicolas Hoizey Sep 26 '21 at 20:15
5

The sizes attribute does make a difference and is required if you use w-descriptors. Take a look at the following example:

<img srcset="
    https://via.placeholder.com/200x150?text=200w&v=1 200w,
    https://via.placeholder.com/400x300?text=400w&v=1 400w,
    https://via.placeholder.com/800x600?text=800w&v=1 800w,
    https://via.placeholder.com/1200x900?text=1200w&v=1 1200w
" style="width: 200px">

<img srcset="
    https://via.placeholder.com/200x150?text=200w&v=2 200w,
    https://via.placeholder.com/400x300?text=400w&v=2 400w,
    https://via.placeholder.com/800x600?text=800w&v=2 800w,
    https://via.placeholder.com/1200x900?text=1200w&v=2 1200w
" style="width: 200px" sizes="200px">

It shows two images with the same srcset but one of them has a correct sizes attribute. The one with sizes loads the correct image, the other doesn’t. This is because if the sizes attribute is omitted the browser uses the default value 100vw.

To change images only based on the device-pixel-density use x-descriptors instead.

For art-direction use <picture> with <source> elements.

ausi
  • 7,253
  • 2
  • 31
  • 48
  • I'm assuming something changed in the way browsers handle srcset without sizes, because, for me, the first image is behaving as expected while the second image is not. – Stefan Teunissen Mar 08 '22 at 08:45
  • @StefanTeunissen No, nothing changed there. What do you see if you run the code example from above? What browser are you using? – ausi Mar 08 '22 at 10:00
  • I'm using Brave on Chromium 99.0.4844.51. The first image will use 200x150 from the start, 400x300 above a width of 400, 800x600 above 800, and 1200x900 above 1200. The second image decides to always stay on 200x150. – Stefan Teunissen Mar 08 '22 at 11:14
  • @StefanTeunissen This is the correct behavior. The image should stay on 200x150 because its size (set via `width: 200px`) stays the same for all screen sizes. – ausi Mar 08 '22 at 12:29