After a lot of reading over the weekend and a fair bit of discussion on the WHATWG mailing list, I’ve come to a couple of conclusions:

Initially, I totally misunderstood how <img srcset> works

I still don’t want it, and still do want <picture>

The appeal of <picture> is that you can select different image sources based on any media query, giving you fine control over which version is served under various conditions. Currently this includes viewport width/height, device orientation, pixel density, colour capability etc, and as more media queries arrive (surely there will be a connection speed query sooner or later, and I’d love to see containing element width/height as well) the element becomes even more useful and flexible. Initially, I thought <img srcset> was an attempt to avoid creating a new element by shoehorning this functionality into a new attribute.

In fact, <img srcset> comes from a radically different angle. For each version of the image, we add an entry to the srcset attribute with the filename, and optionally the width, height and resolution (expressed as “1x”, “2x” etc). The user agent then decides which version to serve, based on the metadata we’ve given it and the current conditions on the client (viewport, connection speed, pixel density, user settings, etc). Unlike <picture>, authors aren’t specifying which source to use and when; rather, we’re just telling the user agent what’s available and letting it make the call on its own. <img srcset> allows authors to provide lots of different versions of an image, but affords us no control over when they are used.

Update: I had this wrong, and so did quite a few other people. There’s still some ambiguity, with the spec contradicting itself in places. Jeremy Keith has done an excellent job of clearing up what the parameters in srcset actually do in his post today.

When we practise responsive design, we are trying to give the best possible experience to our users by adapting our websites to work with whatever they are using to access them. <picture>, by design, gives us the control to do this with content images. <img srcset>, by design, takes it away.

Of course, <picture> is imperfect (duplication of alt attributes is annoying, as is the potential duplication of media queries on some pages), but in my view it’s the best path to continue down.

It’s interesting, because on the WHATWG mailing list the other day I mentioned how nice it would be to have a media query that tests containing element width, to which the response was effectively “you can’t wait until after the CSS is applied to decide which image to download”. Okay, but it’s hard to see how the srcset proposal would work properly without waiting for CSS to be applied so the “available width” is known.

In his long email, Ian Hickson addresses the “available width”. He basically says change it from available width to viewport (e.g. window.width) because you can’t get the available width without processing layout information.

“The net result of this [processing srcset before getting layout info] is that we can just change the proposal above to
use the viewport dimensions instead of the available width, and it should
work about as well. It does mean, though, that we can’t use the height=””
and width=”” attributes as fallback dimensions for the other ones.”

I don’t really see how this is going to work… if I have 3 images, one at 256, one at 512 one at 1024, and my viewport is 1024, but the image is 25%, by this setting the image according to view port width the UA is going to load the 1024 image, which is four times larger than what’s required

<picture> could work better here because authors know the context the image is going to be in and can specify appropriate versions accordingly.

Because of the shortcoming you describe, I feel I could only use srcset for handling different pixel densities – a valid and increasingly important use case, but only one part of the responsive images problem in my view.

As it happens, I do share your concerns about a connection speed media query. There’s also the opposite scenario to what you describe: a normal quality version gets cached whilst on a slow connection, then you move to a fast connection – does the UA serve the normal quality version from the cache, or download a high quality version?

Anyway, there would hopefully be some logic in place to prevent the kind of unwanted behaviour you’re talking about.

I fear that if you try to do too much this entire proposal will collapse.

Do just one thing, and do it well: Different images for different DPI’s of the agent.

You want a different image for different screen sizes? That’s something else, and should not be mixed in because you will get bogged down getting the details perfect, technology will march on and someone will come up with an imperfect solution that’s good enough, and then this entire working group will be for naught.

This group was not formed to find a solution just for different pixel densities. The point was, and is, to be able to serve different sources based on a variety of conditions.

I would argue that by reusing the syntax of <video> and also reusing media queries, the <picture> proposal is a very uncomplicated solution. It’s not “trying to do too much”, it’s trying to do exactly what we want.

If this group was not formed to find a solution for pixel densities, srcset is not a concern for you. You are solving completely different problems. srcset’s purpose is to handle higher resolution versions of the same image. picture is to select different images depending on what layout. Whether srcset is used to solve the pixel density problem is unrelated to whether picture is used to solve your problem. (Except in so much as the syntaxes interacting. Presumably the source element should get a srcset attribute too.)

On displays with high pixel densities, CSS pixels don’t correspond to device pixels. They get scaled up so each CSS pixel is, e.g., 2×2 device pixels. It’s as if you view the page with a 200% zoom. Correspondingly, images are “scaled up” so that one pixel on the image is one CSS pixel. This is not ideal for high pixel densities. Ideally, on an image where CSS pixels are scaled double for device pixels, we could get an image sized in device pixels and drawn “scaled down” in CSS pixels so that, at the end of the day, pixels in the image correspond to pixels in the screen. The usual way to do that is to combine an image with more pixels with some way to scale the image.

srcset solves that problem. In fact, picture doesn’t even address that use! You need not only to select the larger image, but also to specify that the image is scaled down in CSS pixels. Picture does not provide the latter. Picture also cannot address this as, fundamentally, this is a UA decision. Likewise, srcset fundamentally cannot solve your problem as this is an author decision. Nor has it ever tried to. This conflict would be easily resolved if the grop stopped viewing it as an “us versus them” thing. It’s not. You have been comparing apples and oranges.

I disagree somewhat that pixel densities is the driving characteristic. I’m disturbed by the emphasis in device pixel ratio in the syntax. As a web developer, I shouldn’t be directly concerned about pixel density – I should be concerned about the number of available device pixels, which only indirectly relates to pixel density.

Do I really want to supply a different image just because the device has a pixel density of 2x? Probably not. More likely I want to supply a specific image because the number of CSS pixels times the pixel density is over a certain value. Put another way, does anyone use the 1x, 2x, etc., syntax without doing the math?

What I’d really like to be able to do is have media queries that measure width in CSS px or em, etc., for things like divs, and measure width in device px for images.