Wrong source chosen from img srcset when html font size is non-default and "sizes" attribute source size value is in rems
Categories
(Core :: DOM: Core & HTML, defect)
Tracking
()
People
(Reporter: bart, Unassigned)
Details
User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:108.0) Gecko/20100101 Firefox/108.0
Steps to reproduce:
I have a page whose base font size has been customized. For demonstration purposes, an admittedly silly 10px.
I have an image with a srcset (width descriptors) and a sizes attribute. The sizes attribute says the image is always 30rem wide. Via CSS the image is also styled to be 30rem wide.
A test case is available at https://codepen.io/tremby/pen/yLqVYxr
Actual results:
The wrong source is being loaded. The browser seems to believe the image is being rendered at 480px wide when in fact it is 300px wide. It seems it believes 1rem is still at the default of 16px.
Expected results:
30rem means 30 times the font size of the html element, which is 10px, so 30rem means 300px. The layout engine gets this correct and renders the image 300px wide. Whatever logic parses the sizes attribute, figures out what size the image should be rendering at, and then picks the most suitable source from the srcset should also be using the correct value for the rem unit.
Chrome shows the same behaviour. This makes me wonder if I'm trying to do something the spec doesn't allow. However, I can't figure out what, if so.
https://html.spec.whatwg.org/multipage/images.html#sizes-attributes
"A <source-size-value> must not be negative, and must not use CSS functions other than the math functions." -- I don't think I'm breaking that rule.
"Percentages are not allowed in a <source-size-value>, to avoid confusion about what it would be relative to. The 'vw' unit can be used for sizes relative to the viewport width." -- I don't think I'm breaking that rule either.
It otherwise just says it needs to be a <length>, and when I follow that link, rem is one of the listed units.
Why am I doing this?
What I actually want to do is have a variable base font size, so the whole page scales nicely (for example, html { font-size: max(18px, calc(10px + 1vw)); }). Then on the page I want a container with a max-width specified in units of rem, for optimal readability. Once I had done that, setting sizes attributes on images in vw units got very awkward, so I want to use rem units instead. I came across this issue while trying to achieve that.
| Reporter | ||
Comment 1•3 years ago
|
||
On rereading I see wasn't as clear as I could be:
Actual results:
The 480x240 source is chosen.
Expected results:
The 300x150 source is chosen.
| Reporter | ||
Comment 2•3 years ago
|
||
So, the real world sizes attribute I wanted to use was sizes="(max-width: 32rem) calc(100vw - 2rem), 30rem". That's fine at 32rem viewport width and below, but broken when wider than that, consistent with this bug report.
For now, I have to recalculate the rem in this sizes attribute. My rem is defined with html { font-size: max(18px, calc(10px + 1vw)); } so I'm doing sizes="(max-width: 32rem) calc(100vw - 2rem), calc(30 * max(18px, calc(10px + 1vw)))". This works perfectly but is rather unpleasant.
Comment 3•3 years ago
|
||
The Bugbug bot thinks this bug should belong to the 'Core::DOM: Core & HTML' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.
Comment 4•3 years ago
|
||
I think this is invalid. Media queries can't depend on root font size, so the font-size we use is the initial one. See https://drafts.csswg.org/mediaqueries-5/#units which specifies this.
| Reporter | ||
Comment 5•3 years ago
|
||
Huh. OK.
This means that in some contexts rem means one thing, and in other contexts it means something else. This is a shame.
Comment 6•3 years ago
|
||
It's to prevent cycles. For sizes maybe we could make an exception (may be worth filing an issue in https://github.com/whatwg/html/issues/new or so?), but not generally, since they can trivially cause cycles:
@media (width > 1rem) {
:root { font-size: 100000px }
}
Or so.
Description
•