-
Notifications
You must be signed in to change notification settings - Fork 715
[css-animations] The "via" keyframe selector #6151
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
One thing to consider is that at the moment the order of the keyframe rules doesn't matter. When a keyword like Also, the keyframe selector takes a comma-separated list, so that also applies in that case. So the following case @keyframes x {
from { color: blue; }
via, via, 30%, via { color: yellow; }
to { color: lime; }
} would then be equivalent to @keyframes x {
0% { color: blue; }
10% { color: yellow; }
20% { color: yellow; }
30% { color: yellow; }
65% { color: yellow; }
100% { color: lime; }
} Sebastian |
I must admit, I did not consider the order as I rarely ever make use of this feature, but in the case that the "absolute" keyframes selectors aren't ordered properly, there are two things we could logically do.
So let's say we have @keyframes blink {
90% { opacity: 1; }
via { opacity: 0; }
0% { opacity: 1; }
} Then the first rule would say "this |
Another possible solution could be the ability to specify the ending percentage, defaulting to 100%. So you would write @keyframes rainbowText {
@end 4%;
0% { color: red; }
1% { color: orange; }
2% { color: yellow; }
3% { color: green; }
4% { color: blue; }
} Then remove orange @keyframes rainbowText {
@end 3%;
0% { color: red; }
1% { color: yellow; }
2% { color: green; }
3% { color: blue; }
} |
@Loirooriol while that does solve the decimals, it does not address the issue that you need to edit multiple keyframe selectors upon adding or removing one (e.g. if I want to remove |
I agree with @vrugtehagel about your proposal, @Loirooriol. Instead of bending the meaning of the percentages that way, integers would make much more sense in this case. Then the keyframes would be sorted by them, ascending. By that I mean that the integer values would only define the order of the keyframes but not have any meaning on where exactly the keyframe is positioned, i.e. they would be evenly spread across 0% and 100%. So, instead of @keyframes rainbowText {
@end 4%;
0% { color: red; }
1% { color: orange; }
2% { color: yellow; }
3% { color: green; }
4% { color: blue; }
} you'd write something like @keyframes rainbowText {
0 { color: red; }
10 { color: orange; }
20 { color: yellow; }
30 { color: green; }
40 { color: blue; }
} or @keyframes rainbowText {
0 { color: red; }
5 { color: orange; }
10 { color: yellow; }
15 { color: green; }
20 { color: blue; }
} Both of them would be equivalent to @keyframes rainbowText {
0% { color: red; }
25% { color: orange; }
50% { color: yellow; }
75% { color: green; }
100% { color: blue; }
} Then removing one keyframe or adding one in between would be less of a problem. Though one disadvantage would be that you don't have any influence on the exact positioning of the keyframes as they are evenly spread. And if you added more keyframes in between two keyframes, you'd still have to adjust one of them. Furthermore, @vrugtehagel's suggested syntax is less disruptive and integrates better with the exising @vrugtehagel Note that an @keyframes x {
90% { opacity: 1; }
via { opacity: 0; }
0% { opacity: 1; }
50% { opacity: 0.5; }
} (Not saying, anybody should actually write a rule in such a chaotic order. 😄) Another case that needs to be specified is what happens when a
In this case, I'd prefer option 3, as it is the nearest to what was suggested. Sebastian |
I indeed agree with option 3 there. We can already leave out the start and end of a keyframe animation; the specs clearly state
I would not like to change this; @keyframes hop {
via { transform: translateY(-10px); }
} would mean it resolves to 50%, and, as the specs currently specify, 0% and 100% will be constructed using the computed values. I think the biggest ambiguity we have is what happens when, for example, someone writes @keyframes fadeOutIn {
0%, 90% { opacity: 1; }
via { opacity: 0; }
50% { opacity: 0.5; }
} Even without the @keyframes fadeOutIn {
0% { opacity: 1; }
50% { opacity: 0.5; }
70% { opacity: 0; }
90% { opacity: 1; }
} That is, even when using keyframe selector lists (such as |
Can anyone think of a case where you would actually want to build your I would suggest having a look at how GSAP and AnimJs handle keyframes. These are just a few examples. Having used many different animation libraries over the last 20 years, I'd really love to see CSS come closer to their syntax. It's way more flexible for defining where you want different easing types and durations to occur, how long your overall animation should run and for interrupting animations and changing the motion paths to a new animation midway through. I don't want to blow up the scope of this issue. I think the |
Yes, the most obvious case is something like |
Writing your keyframes out of order can be useful. Specifically, people tend to do this whenever blocks to different keyframes are the same; it allows you to entirely omit one of the blocks. Tabatkins shows a simple example, but it extends to bigger animations as well. This is a good point, though; if you have big animations, shortened by grouping some of the keyframes into lists of keyframes, then However, I still think Turns out, about 89.96% of all keyframe definitions are defined in the proper order. Tabatkins' example is, funnily enough, only the second most common case with 0.8%. The most common (at 1.3%) non-ordered animation is this: @keyframes mostCommonWeirdlyOrderedAnimation {
0%, 60%, 75%, 90%, 100% { ... }
0% { ... }
60% { ... }
75% { ... }
90% { ... }
100% { ... }
} which looks like it could be Either way, just by the fact that only 10% of the keyframe animations are not in the correct order, I'd say As far as a separate rule like |
YES let's please address the use case! As an author I have very frequently been frustrated with this. Out of the ideas proposed above, the one with I’ll add another idea to the pile, possibly bad but it may help brainstorming. What if we could invert the grouping of keyframes and properties, and we could just list the values a given property will go through and have the UA automatically figure out the keyframes, akin to how gradient color stops work? I.e.
Note that this would allow us to do things like:
without all the annoying math this would require to do with keyframe percentages. |
The Web Animations API allows this. That is, you can provide a list of keyframes or a list of values per property. See the examples at: https://drafts.csswg.org/web-animations-1/#processing-a-keyframes-argument It also allows omitting the keyframe offsets in either case. Whatever we do here should probably align with that to some extent. |
@LeaVerou that's a great idea! The syntax looks a bit weird to me, but I suppose we can't really accomplish that idea without new syntax. I thought first that separating the values with @birtles makes a good point as well. We can define a
The only difference here is that in JavaScript, your keyframes must be in the right order whereas CSS allows you to define them in any order you want. Anyway, while I do really like the concept of being able to "invert" the keyframe definition as LeaVerou suggested, I would again lean towards that being a separate proposal. That and this proposal are similar and obviously related but are simply different features, and solve slightly different use cases. Let me illustrate this with an example: @keyframes wiggleThenRainbow {
0% { left: 0; }
10% { left: -10px; }
20% { left: 10px; }
30% { left: -10px; }
40% { left: 0; color: black; }
55% { color: red; }
70% { color: blue; }
85% { color: yellow; }
100% { color: green; }
} This animation is hard to write with inverted notation (if even possible at all) but would benefit from However the inverted syntax would be very useful for cases like this: @keyframes wiggleAndRainbow {
0% { left: 0; color: black; }
20% { color: red; }
25% { left: -10px; }
40% { color: blue; }
50% { left: 10px; }
60% { color: yellow; }
75% { left: -10px; }
80% { color: green; }
100% { left: 0; color: black; }
} You could, in this case, use @keyframes wiggleAndRainbow {
from {color: black; }
via { color: red; }
via { color: blue; }
via { color: yellow; }
via { color: green; }
to { color: black; }
from { left: 0; }
via { left: -10px; }
via { left: 10px; }
via { left: -10px; }
to { left: 0; }
} That would, similar to the previous example, simplify adding or removing a wiggle or rainbow color, though the inverted syntax would most definitely make more sense than |
I agree with that. For what it's worth, a keyword could also be used for that syntax instead of the semicolon, e.g. @keyframes rainbowText {
color {
values: red to orange to yellow to green to blue;
}
opacity {
values: 0 to 1 to .5;
}
} That's probably not as readable as using an existing separator in some cases but wouldn't conflict with existing syntax.
Having multiple animations within one > @keyframes rainbow {
> from {color: black; }
> via { color: red; }
> via { color: blue; }
> via { color: yellow; }
> via { color: green; }
> to { color: black; }
> }
>
> @keyframes wiggle {
> from { left: 0; }
> via { left: -10px; }
> via { left: 10px; }
> via { left: -10px; }
> to { left: 0; }
> } And then animate them individually within Sebastian |
@SebastianZ the last example I gave, |
We recently discussed which separators we can use for arbitrary values, as it was needed for |
Proposal: the
via
keyframe selectorProblem
When we write CSS keyframe animations, especially large ones, it is not uncommon that we need to add or remove a keyframe. In a lot of cases, the keyframe selectors are evenly-spaced, so adding a keyframe requires us to edit every keyframe selector in that animation. For example, say we wrote:
Now, we test it and see the orange is a bit ugly, and we want to remove it. We rewrite the above to
We now notice it's not very rainbow-ey, so want to try to re-add orange, but add purple too this time... We rewrite all the keyframes, etcetera, you get the point.
There's two issues here:
66.667%
in the above example)Proposal
Here's my solution to this: the
via
keyframe selector. Essentially, it would linearly interpolate between the closest bounding absolutely specified keyframe selectors. Let me demonstrate by example.Example usage
The original
rainbowText
animation would end up looking likeNow, adding a keyframe is a breeze, because we don't need to worry about the keyframe selectors for the other keyframes. A little more of a complex example, showing how you can mix
via
and absolute keyframe selectors:The
via
keywords interpolate between the bounding absolute keyframe selectors (25%
and50%
), so it would be equivalent toThis would also allow for keyframe selectors like (I'll list them out here rather than making up a long animation to demonstrate)
[from, 10%, via, via, 40%, 52%, 70%, via, 80%, to]
, which would be equivalent to[0%, 10%, 20%, 30%, 40%, 52%, 70%, 75%, 80%, 100%]
.Links
Original discourse post (also by me): https://discourse.wicg.io/t/proposal-css-keyframes-via-keyword/5219
Relevant part of the spec: https://drafts.csswg.org/css-animations/#typedef-keyframe-selector
The text was updated successfully, but these errors were encountered: