Open graouts opened 2 years ago
Perhaps we could accept 2 values of <easing-function>
in the animation
shorthand, and then the first one will always be the animation-timing-function
, and the second one, if exists, will be for effect-wide easing function?
Another option, if we go with animation-easing
, is to make it a shorthand itself for -keyframe
and -effect
and then a single value will map to -keyframe
and animation-timing-function
, and 2 values would map to both, like
animation-easing: linear ease;
Which would make it backwards compat with animation-timing-function
, and then we could also completely replace it in the shorthand and deprecate -timing-function
.
But this option might still be confusing when mapped to Web Animations.
ping @graouts @birtles @flackr @dbaron @bramus could we make this fit into agenda for TPAC? Anything we can agree on to progress this for agenda?
I'm not attending TPAC I'm afraid but I don't have particularly strong opinions on this.
I tend to prefer @graouts original proposal simply because having a shorthand that puts the keyframe effect first seems a little awkward. Most often authors will only want to set the effect-wide easing (more accurately, iteration-wide, but hey) so having to write linear ease
is a bit cumbersome and error-prone. The backwards compatibility is great though.
In terms of things we agree on, I think everyone agrees we want a way to set effect-wide easing from CSS.
I think most of us would like, if possible, to transition towards using the "easing" terminology over the more verbose "timing function" terminology because that's the name of the member in the Web Animations API and the name of the spec that defines these easing functions.
Another way tackle this could be introducing a new separated property that controls the "mode" of the specified easing to control whether timing function in shorthands are used per keyframe or per iteration. Something along the line of (TBB):
* {
animation-easing-mode: iteration; /* or `keyframe` */
}
And then, like in the above example, you can set it once as default for all and only override where/if needed otherwise.
Also, this probably shouldn't replace the animation-easing
proposal, just allow its introduction into shorthands.
@birtles @graouts
WDYT?
I think that would work but I still prefer @graouts' original proposal for its simplicity. Is there any particular concern with that proposal?
Is there any particular concern with that proposal?
There's no problem, I'm only trying to find a simple way forward to have that easing property work in animation
shorthand seamlessly.
if the animation-easing is set on either the element or a keyframe, then the animation-timing-function values would be completely disregarded, therefore deprecating that property in favor of the new animation-easing which I think would be more user-friendly.
I think more detail is needed about what exactly is meant by "disregarded". I believe what you intend is that the default animation-timing-function
becomes linear
unless an alternative is specified in an animation-easing
rule for a particular keyframe. However, we would only be able to do this if animation-easing
was set to a non-initial value, and given that the default effect-wide easing is linear, linear would be a good choice, except that then the following would not actually result in a linear animation:
.target {
animation: my-animation 1s;
animation-easing: linear;
}
So I think to do this we would have to have an auto
value which would compute equivalent to linear except that it wouldn't trigger ignoring animation-timing-function
.
For a slightly different proposal, we could treat animation-easing
as a set-to-linear shorthand for animation-timing-function
. This would mean that having animation-easing
listed would set animation-timing-function
to linear
, but it could be subsequently overridden if the developer wanted to give a different keyframe easing. This is similar to other reset-only shorthand properties.
E.g. an author could explicitly reset the animation-timing-function
after animation-easing
:
.target {
animation: my-animation 1s; /* animation-timing-function is initially ease as always */
animation-easing: steps(10); /* implicitly sets animation-timing-function to linear. */
animation-timing-function: ease; /* explicitly sets animation-timing-function back to ease. */
}
One challenge about this entire space is that it will still be difficult to add the effect-wide easing to the animation shorthand since it would have to come second there anyways without some other syntax to specify that you want to set the effect-wide easing.
E.g.
.target {
animation: my-animation 1s ease steps(10);
}
I think more detail is needed about what exactly is meant by "disregarded". I believe what you intend is that the default
animation-timing-function
becomeslinear
unless an alternative is specified in ananimation-easing
rule for a particular keyframe.
How would setting the iteration-wide easing inside a keyframe work? Would it reset the progress from that point? If not, what use-cases would that serve?
So I think to do this we would have to have an
auto
value which would compute equivalent to linear except that it wouldn't trigger ignoringanimation-timing-function
.
If we add another auto
wouldn't that be a problem in the animation
shorthand?
For a slightly different proposal, we could treat animation-easing as a set-to-linear shorthand for animation-timing-function.
I thought that was the initial proposal. You mean it would treat the linear
value as "auto" until animation-easing
is explicitly specified?
Another option we can consider for solving the shorthand problem is using a new "mode" property like I suggested above.
The proposed animation-easing-mode
seems like the cleanest as it doesn’t have the problem of animation-easing
and animation-timing-function
fighting against each other.
One downside though, is that you’re then limited to either effect-timings or either keyframe-timings – you can’t have both. Not sure if that’s a limitation that would bother most people or not.
Another approach is to not auto-set animation-timing-function
to linear
when animation-easing
is used, requiring authors to be explicit about both. Maybe a shorthand to set both in one go could also be created?
As for the shorthand: that’s a recurring problem which I don’t think we’ll be able to solve here.
How would setting the iteration-wide easing inside a keyframe work? Would it reset the progress from that point? If not, what use-cases would that serve?
It would not be a valid property inside a keyframe, like other animation affecting properties.
So I think to do this we would have to have an
auto
value which would compute equivalent to linear except that it wouldn't trigger ignoringanimation-timing-function
.If we add another
auto
wouldn't that be a problem in theanimation
shorthand?
If we used auto, I'd propose it is only specified through omission.
For a slightly different proposal, we could treat animation-easing as a set-to-linear shorthand for animation-timing-function.
I thought that was the initial proposal. You mean it would treat the
linear
value as "auto" untilanimation-easing
is explicitly specified?
I'm a bit confused here. If animation-easing is unspecified, then the animation easing will be linear (as it is today), and the animation-timing-function will have its default ease value unless another is specified by the developer. If the developer sets animation-easing: linear
my thinking was that we would want to then replace the initial animation-timing-function: ease
value with animation-timing-function: linear
as well to respect the specified linear. This requires that the initial "linear" value and the specified "linear" value are handled differently.
Another option we can consider for solving the shorthand problem is using a new "mode" property like I suggested above.
I'm not a fan of changing the interpretation of the timing function, but accept this may be the direction we have to go here.
@bramus:
One downside though, is that you’re then limited to either effect-timings or either keyframe-timings – you can’t have both. Not sure if that’s a limitation that would bother most people or not.
That's a good point. I'm trying to think about use-cases but can't think of any.
I guess authors could as well do something like:
* {
animation-timing-function: linear;
}
And then only work on animation-easing
. That could leave the option to have both maybe?
@flackr:
How would setting the iteration-wide easing inside a keyframe work? Would it reset the progress from that point? If not, what use-cases would that serve?
It would not be a valid property inside a keyframe, like other animation affecting properties.
Yes, that was my thought.
If we used auto, I'd propose it is only specified through omission.
Right, that sounds good, still leaving us with the shorthand problem.
I'm a bit confused here. If animation-easing is unspecified, then the animation easing will be linear (as it is today), and the animation-timing-function will have its default ease value unless another is specified by the developer. If the developer sets animation-easing: linear my thinking was that we would want to then replace the initial animation-timing-function: ease value with animation-timing-function: linear as well to respect the specified linear. This requires that the initial "linear" value and the specified "linear" value are handled differently.
OK, I wasn't sure this is possible via an unspecifiable/ommitted auto
, but I guess we're on the same page now.
To sum it up, I think we have an agreed way forward for reseting keyframe-wide to linear
behavior. It's just the shorthand that's still an issue.
We could also go with a solution that allows setting only the iteration-wide function and then authors could still override in the @keyframe
itself per keyframe
Reading through this again, I think I didn't understand @flackr's suggestion before, but I think I got it now 😅
So, what if we made animation-easing
have a non-specifiable initial value of something like none
, which computes to linear, but doesn't reset animation-timing-function
.
Then, when specifying animation-easing
it resets animation-timing-function
to linear
, like suggested above. In most cases (almost all) authors wouldn't want to override animation-timing-function
again, but they can, like above.
Also, like suggested above, allowing easing
to also take 2 values, if needed, can also be used to set the keyframe-wide easing and then iteration-wide one, which can also later be used inside the animation
shorthand.
So in short, I propose to accept @flackr's suggestion above, with the suggested none
non-specifiable initial value.
Currently, the
animation-timing-function
property set on an element will set the default value foranimation-timing-function
for each keyframe of a@keyframes
applied to that element. This means that there is no way to set the easing for an animation effect, only on its keyframes, thus not allowing authors to specify a CSS Animation with multiple keyframes with a single easing being applied throughout.This always bugged me and resurfaced while discussing https://github.com/w3c/csswg-drafts/pull/6974 with @birtles.
One idea @birtles suggested in this conversation would be to add a new
animation-effect-timing-function
property which would apply animation-wide. This is a good suggestion.An alternative I could think of would be to use the term
easing
since this is the name of the property used in the Web Animations specification and also the term used in the CSS Easings specification. Thus, we could introduce a newanimation-easing
property.That property could apply to keyframes as well, where the
animation-easing
property would override the value set on the element for this particular keyframe. And if theanimation-easing
is set on either the element or a keyframe, then theanimation-timing-function
values would be completely disregarded, therefore deprecating that property in favor of the newanimation-easing
which I think would be more user-friendly.