Closed tabatkins closed 2 months ago
My main concern is that transition-behavior
is specifically for transitions, but auto-coercion to calc_size to support smooth interpolations is applicable to css animations and web animations.
I.e. there are three ways to trigger an animation of size:
<style>
.small { height: 0; }
.target { transition: height 1s; }
</style>
<script>
document.querySelector('.target').classList.remove('small');
</script>
<style>
@keyframes expand { from { height: 0; } }
.target { animation: expand 1s; }
</style>
document.querySelector('.target').animate([
{height: '0', offset: 0}
/* Implicit to keyframe */
],
1000);
It would be nice to use a property that opts into all of these working instead of only having transitions work but animations still be discrete.
Options:
transition-behavior: interpolate-sizes
(name to be bikeshedded) then we'd also need an animation-interpolation-behavior
and a property on the web animation api.I think the other question here is whether it's desirable in this case that it's part of the transition
shorthand. I think there was some suggestion (although maybe not) in the meeting today that people might want to enable this "globally" (although I think that becomes a bad idea for more complex sites built from components).
If this is enabled by transition-behavior
(which is part of the transition
shorthand), then enabling "globally" would probably:
!important
allow-discrete
or not (where using allow-discrete
may be problematic if transition-property: all
is used, and not using it may be problematic for any of the use cases that require it such as transitions involving content-visibility
or display
).But maybe enabling "globally" isn't really a use case; I think it's probably undesirable for sites that are built from component pieces. Given that, I think it's probably OK for it to be a part of the transition
shorthand and part of transition-behavior
as long as there's an equivalent for animations and web-animations (see previous comment).
Though, regarding that comment, I'm not quite sure what you meant by:
- We introduce a property to refer to the interpolation behavior.
I'm not quite sure what you meant by:
- We introduce a property to refer to the interpolation behavior.
I hesitate to suggest a specific name because I'm failing to think of a good one right now, but let's say interpolation: calc-lengths
. This would apply the automatic coercion to calc-size any time we are trying to interpolate to/from a discrete length for all CSS transitions, CSS animations and web animations. This would also make specifying transition-behavior
unnecessary as it would now no longer compute to a discrete transition.
@flackr Do you mean that just by * {interpolation: calc-lengths;}
and then with transition: height .3s
we can enable transitions everywhere?
@flackr Do you mean that just by
* {interpolation: calc-lengths;}
and then withtransition: height .3s
we can enable transitions everywhere?
Yes, exactly. When we determine whether we can interpolate between auto
and 100px
we check the computed interpolation
property, and with it being calc-lengths
it would coerce these to interpolable calc-size values, which is what the prototype patch that @dbaron shared did, but did so unconditionally which results in compat issues.
That's great, I support the proposal for the interpolation: calc-lengths
, maybe the name needs to be discussed.
For what it's worth, I think I still lean towards including something in transition-behavior
and in a property that's reset by the animation
shorthand. I think mode switch properties are generally a bad design in CSS. They don't work well with multiple aspects of the cascade: action-at-a-distance when declarations from very different places interact with each other, and also cascading itself in terms of handling overrides.
That said, I'm not completely against interpolation
but I think it has a design smell similar to that of box-sizing
.
My only rejoinder to your comment is that box-sizing
has legitimate reasons to be set to either of its major values, depending on your use-case. This, on the other hand, is just a backwards-compat fix; the behavior it's changing is just "doesn't animate at all", which doesn't really have any use-case except for "my page was written before this behavior and is accidentally depending on these values not animating". That's fixable on the authoring end at the same time as you turn the switch on (and, if we do make this an inheritable property, you can band-aid it on specific elements until you can fix their styling).
https://github.com/w3ctag/design-reviews/issues/955#issuecomment-2121492620 also had one good point that I hadn't seen raised before, and that's relevant here: Using calc-size()
at the endpoints as the opt in for the new behavior means that (without extra fallback declarations written by the author) the fallback in downlevel browsers (particularly for transitions) will break not only the animation but also the behavior before or after the animation. However, with a different opt-in mechanism, the fallback behavior for non-supporting browsers will not break the endpoints but only the animation between them, which is less problematic.
Also, I suppose the discussion above has led me to reconsider and be more comfortable with the idea of a "global" opt-in property for this -- that is, a single property that opts CSS transitions, CSS animations, and web animations on the element in to the new animation behavior. If we have such a property, I think my preference is that it be inherited, given that I think inheritance is a more efficient mechanism for setting it "everywhere" than a universal selector is. This would mean opting in would require :root { interpolation: sizing-keywords }
(or whatever we call it) and opting a subtree out would then require #widget { interpolation: auto }
(or whetever we call it).
I'll try to think about naming a bit more.
By the way, SVG has a color-interpolation property.
Let's review the history of how transition-behavior
was added to the specification:
@fantasai proposed a transition-discrete
global property. I think it's conceptually similar to the current size interpolation
property, but I don't know why it wasn't chosen in the end.
At @josepharhar a list of names used to be provided:
From today's perspective, it seems that transition-interpolation
is more appropriate (Is it still possible to change the name?), I think the transition-behavior
name is a failure, many people seeing it for the first time can't tell from the name what the property is used for. I hate adding transition-behavior: allow-discrete
every time I need a transition, I really wish there was a global property that could control it.
So, I propose that the new name be size-interpolation
, and the default value is normal
or auto
, which needs to be selected.
Yeah, I think making the property name more specific than interpolation
is a good idea.
So here are two possible ideas for a property name and values for an inherited opt-in property (as suggested in https://github.com/w3c/csswg-drafts/issues/10294#issuecomment-2127202025 and earlier), with the initial value of the property (for the current behavior) listed first and the value that opts in to the new interpolation behavior (interpolating sizing keywords when possible) listed second:
size-keyword-interpolation
: none
| auto
size-interpolation
: auto
| keywords
(In all cases the size-
could also be sizing-
.)
Do you have thoughts on these? (And on the size-
versus sizing-
question?) Other ideas?
Both options look reasonable to me. I agree with your earlier comment that it should be inherited. I think I have a slight preference for size-keyword-interpolation: auto
as the opt-in since I have a harder time grokking whatsize-interpolation: keywords
means. We could use discrete
instead of none
as the default value since they do in fact "animate" with a discrete interpolation, you just don't get transitions starting because transitions don't start on discrete interpolations (but it can still be animated with CSS animations or web animations).
I like the shorter name, so vote for size-interpolation
.
Adding Agenda+
to discuss and maybe (!) even conclude on naming options here.
(I think my preference agrees with @flackr's comment.)
Between dbaron's proposals, I'd lean towards the former option:
size-keyword-interpolation
: none
| auto
That syntax feels reasonably intuitive to me; it's pretty clear that "none" (as the initial value) means that size keywords don't interpolate, vs. "auto" means some magical interpolation may happen between size keywords.
Whereas: in the other suggestion size-interpolation
: auto
| keywords
, I have less of a good intuition for what the syntax means. It's not obvious whether the keywords
value represents an expansion vs. a limitation on interpolation behavior; i.e. whether it means "also allow interpolation of keywords" vs. "only allow interpolation for keywords (preventing interpolation of other types of values)".
We could use
discrete
instead ofnone
as the default value since they do in fact "animate" with a discrete interpolation, you just don't get transitions starting because transitions don't start on discrete interpolations (but it can still be animated with CSS animations or web animations).
I'm happy with either none
or discrete
as the naming for the initial value here, though I lean slightly towards none
for simplicity.
(none
seems just-as-clear since, colloquially at least, "animation between two values without interpolation" is understood to mean "animation with discrete interpolation between those two values". So "none" seems ~fine from that perspective. And "discrete" doesn't make things especially clearer, with regard to interaction with transition-behavior
. Looking just at the naming, it's not much easier to grok whether/what behavior would change if you specify a transition-behavior
of (a) normal
vs (b) allow-discrete
, alongside size-keyword-interpolation:discrete
. When paired with allow-discrete
, it ends up feeling like you're requesting discrete animation twice with two similar-but-not-quite-the-same syntaxes, which feels confusingly redundant.)
To the extent that we're likely to keep adding switches for interpolation of stuff that doesn't currently interpolate, I think it would make sense to choose a more general name that can accommodate more keywords. If we think authors will want to cascade them independently, we can add longhands; but I think even in that case we should clearly group them together.
Something like
animation-interpolation: normal | size-keywords || transition-discrete || add stuff here
optionally add longhands:
animation-interpolation-size: normal | allow-keywords
animation-interpolation-transition: <'transition-behavior'>
etc.
(Open to other prefixes, but as @yisibl notes, there's also color-interpolation
, so interpolation
alone would be too generic.)
One concern I have with https://github.com/w3c/csswg-drafts/issues/10294#issuecomment-2149359260 is that the two switches we have so far have very different characteristics:
transition-behavior
does not make sense to set globally: it needs to be specified individually for each transition (usually separately for each direction) because it needs to be associated with a step-start
timing function for one direction and a step-end
timing function for the other, depending on the values at the endpoints, since generally you need one of the two values to be the one used for the entire middle of the transition. (Perhaps we should find a way to make this easier, though!)Another concern is that the animation-*
prefix makes it possibly sound like it applies only to CSS Animations and not also to CSS Transitions, when it really applies to both.
I want to note that authors who played with the calc-size
like Temani in āNo more pixel rounding issues!ā post: , or me in one answer to one question in mastodon did also manage to use it for non-animation/transition purposes, using it for modifying some intrinsic size for static cases, so this could be used more widely.
In these cases, neither the āanimationā fits those use cases, or āinterpolationā, as it is less of interpolating the value, but using the intrinsic lengths in the calculations, at least as it works in the current prototype.
My intention is to keep supporting the calc-size()
syntax, but just no longer make it the recommended way to opt in to animations between two values where it's needed at neither endpoint.
The CSS Working Group just discussed [css-values-5] Interpolating calc-size() more generally
, and agreed to the following:
RESOLVED: use the name interpolate-size: numeric-only | allow-keywords, as an inherited property
One other question about the interpolate-size
property: does it go in css-values-5 (which is a little bit odd because that spec doesn't otherwise specify properties), or does it go elsewhere (such as maybe css-sizing-3 or css-sizing-4)?
Per the recent resolution, we've confirmed that, by default, you only get the calc-size() interpolation behavior if at least one side has calc-size() - that is, interpolating from
0
toauto
continues to not work; you have to eithercalc-size(0)
orcalc-size(auto)
(or both).It was requested in the meeting that there be a way to opt into calc-size() interpolation without having to modify the start/end values, similar to how discretely-animatable values don't transition by default, but can be opted into via
transition-behavior
.The most obvious solution is to just use
transition-behavior
, with a new value that indicates we should use the more powerful size interpolation. I think @flackr has an objection to that, tho.