Repository navigation
Authors have no way to ask for a higher or lower pixel density than the browser's default when selecting from srcset #13069
Description
What problem are you trying to solve?
When a browser selects a candidate from a w-descriptor srcset, it targets roughly 1 image pixel per device pixel of the source size resolved from sizes. That target is fixed. Authors can describe layout (sizes), art direction (<picture>), and the candidates on offer (srcset), but cannot say "for this image, aim higher than the default" or "aim lower". The only knob that moves the result is sizes, and sizes is supposed to describe geometry, not intent.
Quality vs. bytes is a per-image tradeoff that goes both ways:
- Fetch less. Below-the-fold, decorative, or secondary images on a 3x phone fetch ~9x the pixels of a 1x image for content the user may never look at closely. The author would take 0.75x or 0.5x and spend the bytes on LCP instead.
- Fetch more. Images the user will pinch-zoom or that the page enlarges in place (CSS
transform: scale, a lightbox), or that carry fine detail (maps, line art, screenshots). Page zoom already re-selects because it changesdevicePixelRatio; pinch-zoom and scripted zoom deliberately do not change it, so nothing ever re-selects for them.
The browser cannot infer any of this. It does not know which images are decorative, which are the product, or which will be zoomed. Those are author decisions with nowhere to go.
What solutions exist today?
Lie in sizes. Inflate or shrink sizes so the browser targets a different candidate. It is the only lever and it has real costs:
- It is incompatible with
sizes="auto"(Add "auto sizes" for lazy-loaded images #4654). You cannot say "auto" and "but 1.5x more" at the same time. - Once Make
sizesdetermine the natural width ofimg#13046 lands,naturalWidthis derived fromsizes, so a dishonestsizesyields a wrongnaturalWidth(related: No way to read an image's true intrinsic dimensions when sizes="auto" (or any w-descriptor srcset) is used #12565, Getting the current source size value of an img #6532). The workaround now corrupts a DOM API. (min-resolution)queries insizesandxdescriptors do not help: still a lie about layout, per-breakpoint rather than per-image, and neither composes withauto.
Prior discussion. #4421 (open) asks for a density cap to protect high-DPR users (maxresolution / maxdpr; #5901 proposes a UA-side cap note). The objection was that protecting users from over-fetching is the UA's job. That objection does not apply here: this is author intent the UA cannot know, in either direction, not a user-protection default. The UA keeps its freedom to clamp.
How would you solve it?
Illustrative only; the problem matters more than the shape.
A content attribute on img (and source), a positive number, default 1, that multiplies the device pixel ratio used for candidate selection. Applied after the source size is computed, so it composes with sizes="auto" and leaves sizes honest.
<!-- far-below-the-fold: trade sharpness for bytes -->
<img srcset="h-800.jpg 800w, h-1200.jpg 1200w, h-1600.jpg 1600w"
sizes="100vw" densityscale="0.75" loading="lazy">
<!-- zoomable product photo: ask for 1.5x more -->
<img srcset="p-600.jpg 600w, p-900.jpg 900w, p-1200.jpg 1200w"
sizes="auto" densityscale="1.5" loading="lazy">In select an image source from a source set, the implementation-defined choice is made against devicePixelRatio × densityscale. First example: a 2x, 800px-wide viewport targets 1200 image px instead of 1600, about 44% fewer pixels. Second: a 600px box on a 1x screen targets 900 instead of 600.
Whatever the final syntax:
- A multiplier, not an absolute.
0.75means the same thing on a 1x laptop and a 3x phone. Absolute DPR targets do not port across devices, which is where Responsive images causes performance issues on high-resolution devices #4421 got stuck. - A hint. Selection stays implementation-defined. UAs may clamp or ignore it under Save-Data, low memory, or their own density cap.
- Orthogonal to everything else. No change to
sizesparsing, the preload scanner, ornaturalWidth/currentSrcsemantics. It only changes which candidate is chosen. - Naming is open. The name should say "multiplier".
Anything else?
Airbnb would use this immediately: lower density on secondary imagery to cut bytes and protect LCP, higher on the few images users zoom. We do this today by lying in sizes, and have no fix once we move to sizes="auto".
Activity
eeeps commentedon Oct 14, 2026
The original intent of the spec was to give user-agents (who have much, much more information about a given users' context and preferences than authors ever can) the freedom to innovate on their actual selection mechanics over time. Authors provide the information UAs can't know in srcset and sizes, and then UAs own the selection decision, which they (hopefully) make intelligently, based (possibly) on information authors can't know.
Chrome did once select smaller resources when users were in a "data-saver" mode. And Chrome also re-uses cached resources, if they're large enough (even if they overshoot the density target). Those are the only two instances I know of of a browser actually using the freedom the spec gives them, but both of them are (or, in the case of data-saver mode, were) hugely significant.
If we do give authors (who know the most about the importance of the content) more influence here, I want the tools they get to be coarse, because UAs do have more information about users' contexts and could do a better job than authors at setting an actual resolution target (even if they currently often don't). Instead of a multiplier that would require the actual selection mechanics to be specified and set in stone (and forbid UAs from making user-focused decisions based on the extra info they have), maybe we could give authors something like
fetchpriority, but for resolution?resolutionpriority?eeeps commentedon Oct 14, 2026
@austinh How is AirBnB actually lying, now? Do you bake the equivalent of a multiplier into your sizes? If so, what is that multiplier set at, in which contexts?
austinh commentedon Oct 14, 2026
We actually lie about the width descriptors instead of sizes - our solution is even more nuanced than the examples given above. We inflate or deflate them based on various metrics we care about. It is indeed a multiplier. It achieves the same result but is technically not spec compliant. However we do so because it works with auto sizing as well as eager sizing and provides us the lever we want that the browser does not.
Another open source example that attempts a similar strategy.
https://github.com/aFarkas/lazysizes/tree/gh-pages/plugins/optimumx
Say we have img.jpeg?w=720 800w this means we can serve a 720 image as if it was an 800w image. We only have so many image variants, but we have fluid grids/containers, and sometimes we want to be able to influence the variant selected at different times. We also have the concept of a density floor and ceiling. This "lying" width descriptor lets us put that all into a math equation that we can tweak. For us, at scale, we've found the balance between quality and performance to be more nuanced and results in significant revenue differences.
Some more examples:
Hero images we may want boosted quality, especially if we know we will perform an animation with a larger image. So we prevent downloading two separate images and just load a larger one up front, even if its oversized for the initial container.
3x devices we may want to cap at 2.5 density because its imperceptible.
We also have the concept of low data mode - and we fetch one ladder lower on our images (720 instead of 960 for example). I know chrome does something similar but webkit/firefox doesnt.
We can do all of this on native quite easily because we control the image fetching pipeline, caching layer etc, on ios/android etc. but the web limits our ability to express these intents. So cross platform parity is another motivator for us.
Basically, we experiment with these values heavily, and right now the browser doesnt give us the ability to do this according to the spec. We can do it with a hack, but would prefer not to.
We think the browsers can continue to clamp or set limits on their own, but we would like a way to influence this with developer intent. Sometimes the browsers don’t know our product the way we do. We would like more power over that choice of image.
noamr commentedon Oct 14, 2026
@eeeps "the browsers would optimize it later" was well intentioned - but in practice, what happened is that interop won, and, to the best of my knowledge/research, no browser ever shipped an implementation-defined nuance for this in the ~11 years that responsive images exist.
I think we should change the mindset, and be clear about which source should be chosen, perhaps allowing UAs more specific leniancies:
In addition we should give authors a bit more control over the knobs, given that the origins themselves measure their performance in context and can account for how they tweak the knobs in their business metrics.
eeeps commentedon Oct 14, 2026
The current escape hatch the spec gives authors if they want to control selection is
<picture>, but if all you want is to control the resolution target in UAs' current defactosrcsetselection algorithm, calculating all thosemediaqueries is quite unwieldy (though theoretically possible).The argument about UAs' main incentive being interop vs authors' being business metrics, which provide tighter feedback loops and are more aligned with better outcomes for users, is a strong one.
I'm sad browsers didn't do more user-contextual adaptation (or even universal density-capping), but I don't want to limit them to the little bit of it that Chrome actually did do, forever. If we defined a more-explicit algorithm with more input from authors, but at the end said, "UAs MAY select a different resource based on user context and preferences" or whatever – do we think UAs could use that in the future? Or is the interop barrier too strong?
Lastly, I worry about complexity. Many authors already struggle with responsive images. I don't want to hold sophisticated authors like AirBnB back, but I also don't want to make responsive images and the mental model we're asking authors to build up around them more complicated than they already are.
noamr commentedon Oct 14, 2026
Perhaps it's better to keep the reality in the spec, and add the implementation-defined escape hatch if and when a UA actually wants to do that?
Otherwise, what would happen in practice with this kind of MAY is that advanced users and frameworks would rely on the de-facto implementation and would game them to act as if they had the right knobs (evidence: that's the current reality), and that would enshrine those de-facto decisions into an unspecified webcompat issue. So it's better to specify them based on what implementations do now, and when we know better, do better.
True, but also this is purely elective no? Authors who don't use it wouldn't/shouldn't suffer from the complexity.
austinh commentedon Oct 14, 2026
Something like densitytarget="2.0" could work.
Its a density target that the browser aims for (default: 1.0, as today) and is completely
Opt-in. I agree on the point of complexity, most websites will just use a simple img tag and maybe a srcset - and could still do that. But advanced users should be empowered too.
We did try to use media queries @eeeps but we found it to be unwieldy and added significant complexity to our source set generation code. It also wasnt ideal with auto sizes.
Then we stumbed upon lying to the browser about the width descriptor in a srcset and realized it simplified our code down to simple multiplication, at the expense of going against the spec and relying entirely on the implementation today. We know that one day our images could break if somehow the browsers changed their implementation. Hopefully that provides more evidence for somehow formalizing some way to do what we are trying to do in the spec.
noamr commentedon Oct 14, 2026
Opened #13077 to discuss the "implementation defined" issue more in general.