You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
sizes=auto images shouldn't use concrete object width to select source #12248
Currently, sizes=auto lazy-loading images use the concrete object size width to select which source to use (see step 3.3 here). This can be problematic since the concrete object size can be affected by the image's (intrinsic) aspect ratio. For example, consider
An implementation can decide to never downgrade the selected source, i.e. once you've selected big.png 1000w and loaded it, you stick with this selection (until a larger image is needed).
That said, it's intended that the image's size for the purpose of sizes=auto calculation to be stable before and after loading an image, which is why size containment is forced. I don't recall why "concrete object size" was used instead of the computed content box width, though.
#9493 changed how this works (but before also used concrete object width); points to #9448
Somewhat relevant comment on the original sizes=auto discussion: #4654 (comment)
There is also the inverse problem - object-fit: cover might fetch an image that's too small, and scale it to fit the object area.
Seems like what we really need is to find a comprehensive solution for 2D-base auto-sizing?
https://drafts.csswg.org/css-images/#the-object-fit changes the concrete object size, so maybe this is why we used it for sizes=auto. The example in OP doesn't use width and height attributes which are recommended in the spec, and would give an aspect ratio I think.
From what I understand, object-fit makes the concrete size of the image depend on two things:
a) The width/height of the container (which can be defined by the image's width/height attributes)
b) The intrinsic aspect ratio of the image (to account for cover and contain etc)
(b) can only be derived from an image that is already fetched.
This creates a circular dependency - as re-fetching the image might bring an image with a different aspect ratio. I don't think this re-fetching is spec'ed. So implementations mostly short-circuit this and assume that the image's width/height attributes also define the aspect ratio.
Are we recommending that authors use the natural width/height (or at least the natural aspect ratio) in the attributes and then correct it to the displayed size with CSS?
That said, it's intended that the image's size for the purpose of sizes=auto calculation to be stable before and after loading an image, which is why size containment is forced. I don't recall why "concrete object size" was used instead of the computed content box width, though.
Yea that makes size containment insufficient because size containment does not affect the post-loading concrete size in the contain/cover cases.
We should probably go with the content box as suggested here and as implemented in blink.
Separately, we should find a way to allow authors better control so that they can load crisp images with object-fit, e.g. let them specify the natural aspect-ratio in advance.
Some more concrete proposal:
Why don't we use the h value (currently specced as future-compat-h as a hint for defining a natural aspect ratio?
Then when selecting a source, we can take that together with w to mean the expected aspect ratio, and then use it in conjunction with the image's computed object-fit to compute a more appropriate source. This would still re-select a source if the object-fit changes, but only based on the aspect ratios in srcset and not based on the image content.
+1, this would solve a real problem for us. At Airbnb most listing photos render with object-fit: cover in fixed-ratio boxes, and the photos are usually wider than the box. Content-box selection alone under-fetches: a 4:3 photo in a 1:1 card is drawn at 1.33x the box width, so it looks soft. A fixed per-image correction doesn't hold up either, because the box's aspect ratio changes across breakpoints and photos in the same grid have different ratios. w/h lets the UA work it out from the real layout. Our CDN/backend already knows source dimensions when it builds srcset, so emitting h costs us nothing.
Some thoughts:
The hint wins after load: if the fetched image's real ratio differs from w/h, don't re-select. That keeps selection independent of image content and rules out loops. It's probably also worth saying whether w/h are in post-EXIF-orientation terms.
Eager images: this only helps sizes=auto. Above-the-fold images with explicit sizes are chosen by the preload scanner before layout, so they'd still under-fetch with cover. Is there anything we could do there, e.g. letting authors declare the box ratio up front? (this is where my densityscale proposal comes in handy)
+1, this would solve a real problem for us. At Airbnb most listing photos render with object-fit: cover in fixed-ratio boxes, and the photos are usually wider than the box. Content-box selection alone under-fetches: a 4:3 photo in a 1:1 card is drawn at 1.33x the box width, so it looks soft. A fixed per-image correction doesn't hold up either, because the box's aspect ratio changes across breakpoints and photos in the same grid have different ratios. w/h lets the UA work it out from the real layout. Our CDN/backend already knows source dimensions when it builds srcset, so emitting h costs us nothing.
Some thoughts:
The hint wins after load: if the fetched image's real ratio differs from w/h, don't re-select. That keeps selection independent of image content and rules out loops. It's probably also worth saying whether w/h are in post-EXIF-orientation terms.
Right! It has to be post-EXIF I think.
Eager images: this only helps sizes=auto. Above-the-fold images with explicit sizes are chosen by the preload scanner before layout, so they'd still under-fetch with cover. Is there anything we could do there, e.g. letting authors declare the box ratio up front? (this is where my densityscale proposal comes in handy)
Perhaps we should allow somtehing like <img sizes="cover 300px 200px"> for the eager version, in conjunction with the h descriptor.
h descriptor (currently ignored) is taken into account to compute a source aspect ratio before fetching. The source aspect ratio defaults to the image's width/height attributes for sources with no h.
In loading=eager sizes=auto mode, the source aspect ratio together with the computed object-fit and the content box are used to compute the source concrete width (which is the expected concrete size if the image content matches the descriptor).
In loading=eager mode, the 2D area and fit can be put directly in the sizes attribute, with a fallback after the comma: <img sizes="cover 300px 100vh, 300px">
Changing the content box or object-fit are relevant mutation for selecting a new source. Changing the concrete size is not, as it can be affected by the image content.
The source concrete width can be used by the browser for source selection (though that's somewhat implementation defined)
@noamr the width and height attributes set aspect-ratio in the UA stylesheet. I think the intent is indeed that they should be used to "set" the aspect ratio, and you can override the box dimensions with CSS.
We can maybe still add the h descriptor, but then I think the purpose should be to improve resource selection rather than only set aspect ratio.
@noamr the width and height attributes set aspect-ratio in the UA stylesheet. I think the intent is indeed that they should be used to "set" the aspect ratio, and you can override the box dimensions with CSS.
aspect-ratio doesn't help because it sets the container aspect ratio and not the image aspect ratio considering object-fit.
We can maybe still add the h descriptor, but then I think the purpose should be to improve resource selection rather than only set aspect ratio.
Yes, the idea here is that honly improves source selection and doesn't affect the resulting aspect ratio.
Activity
emilio commentedon Mar 11, 2026
Yeah so it seems blink is basically doing
HTMLImageElement.widthor so. Seems reasonable to me.vinhill commentedon Mar 11, 2026
Cc @zcorpan
zcorpan commentedon Mar 12, 2026
No, this is not correct. https://html.spec.whatwg.org/#select-an-image-source-from-a-source-set says
An implementation can decide to never downgrade the selected source, i.e. once you've selected
big.png 1000wand loaded it, you stick with this selection (until a larger image is needed).That said, it's intended that the image's size for the purpose of
sizes=autocalculation to be stable before and after loading an image, which is why size containment is forced. I don't recall why "concrete object size" was used instead of the computed content box width, though.#9493 changed how this works (but before also used concrete object width); points to #9448
noamr commentedon Oct 5, 2026
Somewhat relevant comment on the original
sizes=autodiscussion: #4654 (comment)There is also the inverse problem -
object-fit: covermight fetch an image that's too small, and scale it to fit the object area.Seems like what we really need is to find a comprehensive solution for 2D-base auto-sizing?
zcorpan commentedon Oct 5, 2026
https://drafts.csswg.org/css-images/#the-object-fit changes the concrete object size, so maybe this is why we used it for
sizes=auto. The example in OP doesn't usewidthandheightattributes which are recommended in the spec, and would give an aspect ratio I think.cc @whatwg/css
noamr commentedon Oct 6, 2026
From what I understand,
object-fitmakes the concrete size of the image depend on two things:a) The width/height of the container (which can be defined by the image's width/height attributes)
b) The intrinsic aspect ratio of the image (to account for
coverandcontainetc)(b) can only be derived from an image that is already fetched.
This creates a circular dependency - as re-fetching the image might bring an image with a different aspect ratio. I don't think this re-fetching is spec'ed. So implementations mostly short-circuit this and assume that the image's width/height attributes also define the aspect ratio.
Are we recommending that authors use the natural width/height (or at least the natural aspect ratio) in the attributes and then correct it to the displayed size with CSS?
noamr commentedon Oct 7, 2026
Yea that makes size containment insufficient because size containment does not affect the post-loading concrete size in the contain/cover cases.
We should probably go with the content box as suggested here and as implemented in blink.
Separately, we should find a way to allow authors better control so that they can load crisp images with
object-fit, e.g. let them specify the natural aspect-ratio in advance.noamr commentedon Oct 7, 2026
Some more concrete proposal:
Why don't we use the
hvalue (currently specced asfuture-compat-has a hint for defining a natural aspect ratio?Then when selecting a source, we can take that together with
wto mean the expected aspect ratio, and then use it in conjunction with the image's computedobject-fitto compute a more appropriate source. This would still re-select a source if theobject-fitchanges, but only based on the aspect ratios insrcsetand not based on the image content.WDYT?
cc @austinh
austinh commentedon Oct 7, 2026
+1, this would solve a real problem for us. At Airbnb most listing photos render with object-fit: cover in fixed-ratio boxes, and the photos are usually wider than the box. Content-box selection alone under-fetches: a 4:3 photo in a 1:1 card is drawn at 1.33x the box width, so it looks soft. A fixed per-image correction doesn't hold up either, because the box's aspect ratio changes across breakpoints and photos in the same grid have different ratios.
w/hlets the UA work it out from the real layout. Our CDN/backend already knows source dimensions when it builds srcset, so emitting h costs us nothing.Some thoughts:
densityscaleproposal comes in handy)noamr commentedon Oct 7, 2026
Right! It has to be post-EXIF I think.
Perhaps we should allow somtehing like
<img sizes="cover 300px 200px">for the eager version, in conjunction with thehdescriptor.noamr commentedon Oct 8, 2026
To summarize the proposal:
hdescriptor (currently ignored) is taken into account to compute asource aspect ratiobefore fetching. The source aspect ratio defaults to the image's width/height attributes for sources with noh.loading=eager sizes=automode, thesource aspect ratiotogether with the computedobject-fitand thecontent boxare used to compute thesource concrete width(which is the expected concrete size if the image content matches the descriptor).loading=eagermode, the 2D area and fit can be put directly in thesizesattribute, with a fallback after the comma:<img sizes="cover 300px 100vh, 300px">object-fitare relevant mutation for selecting a new source. Changing the concrete size is not, as it can be affected by the image content.source concrete widthcan be used by the browser for source selection (though that's somewhat implementation defined)zcorpan commentedon Oct 8, 2026
Also see #3981
zcorpan commentedon Oct 8, 2026
@noamr the width and height attributes set
aspect-ratioin the UA stylesheet. I think the intent is indeed that they should be used to "set" the aspect ratio, and you can override the box dimensions with CSS.We can maybe still add the
hdescriptor, but then I think the purpose should be to improve resource selection rather than only set aspect ratio.noamr commentedon Oct 8, 2026
aspect-ratiodoesn't help because it sets the container aspect ratio and not the image aspect ratio consideringobject-fit.Yes, the idea here is that
honly improves source selection and doesn't affect the resulting aspect ratio.foolip commentedon Oct 8, 2026
What would the syntax be? Something like
srcset="small.png 100w 50h, big.png 1000w 500h"?noamr commentedon Oct 8, 2026
Yes.
Plus the sizes="cover 300px 100vw" thing for eager images.