transition unexpectedly does not play, when you make a balanced change to font-size and to a value specified in `em` units, such that the resulting computed value is unchanged
Categories
(Core :: CSS Transitions and Animations, defect)
Tracking
()
People
(Reporter: stephan, Unassigned)
References
Details
Attachments
(1 file)
|
639 bytes,
text/html
|
Details |
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:101.0) Gecko/20100101 Firefox/101.0
Steps to reproduce:
See this example:
https://jsfiddle.net/z89jpgv5/
There are label elements with padding specified in em. Upon focusing the inputs the font sizes in each label are reduced to half of their initial size while the padding is increased to twice its initial size (all specified in em), effectively staying the same size visually.
Actual results:
If a padding of 1em is specified in the focus-within rule, it jumps instead of transitioning, as can be seen in the first example with the label with red border. I can only circumvent this by specifying a value other than 1em (i.e. 1.001em, as in the second example with the label with lime green border).
Expected results:
The padding should transition smoothly if a value of 1em is specified.
Comment 1•4 years ago
|
||
The Bugbug bot thinks this bug should belong to the 'Core::Layout: Text and Fonts' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.
Updated•4 years ago
|
Comment 2•4 years ago
|
||
Chromium seems to match Firefox here (showing a jump), for what it's worth.
Safari/WebKit matches the reporter's expected results, though.
Comment 3•4 years ago
•
|
||
It looks like this only happens in cases where the "start" em length (resolved in the "start" font-size) would resolve to precisely the same pixel-value as the "end" em length (resolved in the "end" font-size).
I suspect this triggers a special case where we decline to play the transition for that property (for padding in this case) and we just immediately jump to the new specified value; and then after that jump, it looks like the property starts animating but really it's just holding a fixed specified value in terms of em units, and the value of an em is just changing out from under it.
The Firefox/Chrome behavior here might be required by the spec? I seem to recall that transitions are explicitly triggered (for a given property) whenever the computed value of that property changes. And in this case, the computed value is not changing, which is presumably what makes us skip the transition...
Comment 4•4 years ago
•
|
||
Yeah, the relevant spec quote here is in https://www.w3.org/TR/css-transitions-1/#starting :
When a style change event occurs, implementations must start transitions based on the computed values that changed in that event.
[EDIT: sorry, I initially forgot to include a spec link; I've added the link now.]
In the reporter's JSFiddle, when the :active CSS rule starts applying, it adds new styles for font-size and padding. And this style-change does result in the computed style of font-size changing, but it does not result in the computed style of padding changing.
So, per spec, we play a transition for font-size but not for padding. The padding is the same pixel value before and after the style change. (This is a bit easier to see if you specify your font-size in pixel units.)
Since padding happens to be specified in terms of em units, it does end up changing during the font-size transition due to the fact that the intermediate font-size produce a new resolution oft padding's em units. But padding itself is not directly transitioned, since its computed value (the pixel value) is the same before and after the restyle as-a-whole is applied.
(emilio / hiro / boris, let me know if I'm missing anything here; otherwise I think this is not-a-Firefox-bug since we [and Chrome] are following the spec.)
Comment 5•4 years ago
|
||
Here's my reduced testcase, to (hopefully) demonstrate what's going on here.
(I've changed things from the reporter's testcase to use hover to trigger the new style, and to have width be the property that transitions along with font-size [instead of padding]).
As shown in code-comments in this testcase, the computed width is the same before and after the new style applies, which means it does not generate a transition. However, font-size changes, so font-size does generate a transition. This ends up meaning that width jumps directly to the new specified value (it doesn't transition), though it ends up resolving to different intermediate values while font-size gets transitioned as a result of the fact that font-size is transitioning.
Updated•4 years ago
|
Thanks for looking into this. While this may be according to the specs it’s undesirable from a practical/visual point of view (or would anyone disagree here?). And it’s kind of an obscure issue that took me quite a while to figure out, so it probably caused and will cause a lot of other people to trip over this.
Sounds to me like a negligence when developing the specification. Or perhaps it isn’t that strict in that one could still transition computed values that stay the same if they are explicitly specified (or only if they are specified in em)? I’m just thinking out loudly here.
Comment 7•4 years ago
|
||
(In reply to Stephan from comment #6)
Thanks for looking into this. While this may be according to the specs it’s undesirable from a practical/visual point of view
I agree it's unintuitive at least, yeah.
perhaps it isn’t that strict in that one could still transition computed values that stay the same if they are explicitly specified (or only if they are specified in em)? I’m just thinking out loudly here.
You can't transition computed values when the computed value isn't changing (from 240px to 240px, to use the before/after computed values from my attached testcase).
What I think you really want is the ability to transition between specified values; but that's not how CSS transitions were designed to operate.
CSS Transitions are intended to be a relatively-simple method for smoothing out changes to a property's computed value, which are triggered by restyles. From that perspective, they are "working as-intended" here, even if the results are somewhat unintuitive.
Note that CSS transitions may not always be the right solution, e.g. when you're expressing one property in terms of another while also trying to transition both of them, things may get a little weird. However, I think the hack you've landed on (using a tiny fractional delta to guarantee a change in computed value) is a reasonable way of explicitly triggering the behavior you want.
Comment 8•4 years ago
|
||
If you have a proposal for how you'd like to see this feature change, the right place to ask for that would be with the CSSWG; if there's a spec change that's agreed-upon there, we would presumably implement it or accept a patch to implement it. Feel free to file an issue at the "GitHub Issues" link at the top of the CSS Transitions spec ( https://www.w3.org/TR/css-transitions-1/ )
Comment 9•4 years ago
|
||
(In reply to Daniel Holbert [:dholbert] from comment #2)
Chromium seems to match Firefox here (showing a jump), for what it's worth.
Safari/WebKit matches the reporter's expected results, though.
I probed the Safari/WebKit behavior and it seems to be due to a bug, which I've filed as https://bugs.webkit.org/show_bug.cgi?id=241570
Essentially, they don't transition em values at all (in response to changes in font-size); they just immediately re-resolve the em value with the "after" font-size value. This happens to avoid the issue in the reporter's testcase here, but it creates undesirable effects in other scenarios (like in the testcase that I included on my WebKit bug report).
If/when WebKit fixes that bug, I suspect they'll match Firefox and Chrome here.
(In reply to Daniel Holbert [:dholbert] from comment #4)
Yeah, the relevant spec quote here is in https://www.w3.org/TR/css-transitions-1/#starting :
When a style change event occurs, implementations must start transitions based on the computed values that changed in that event.
Reading further, there's actually a much more detailed multi-step algorithm in the spec which also explicitly calls for our behavior ("For each element and property, the implementation must act as follows: [...]"). Specifically, it requires that "the before-change style is different from the after-change style for that property" (where these styles are defined as computed-values; which have em units resolved away to pixel values).
Updated•4 years ago
|
Comment 10•4 years ago
|
||
(CC'ing kdubost, as a WebKit interop FYI. Hi karl! I tried to CC you on the webkit bug report, but CC autocomplete didn't seem to find you. :) You may want to take a look at https://bugs.webkit.org/show_bug.cgi?id=241570 .)
Description
•