Description
Proposal: the via
keyframe selector
Problem
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:
@keyframes rainbowText {
from { color: red; }
25% { color: orange; }
50% { color: yellow; }
75% { color: green; }
to { color: blue; }
}
Now, we test it and see the orange is a bit ugly, and we want to remove it. We rewrite the above to
@keyframes rainbowText {
from { color: red; }
33.333% { color: yellow; }
66.667% { color: green; }
to { color: blue; }
}
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:
- We need to rewrite every keyframe selector whenever we want to add or remove a keyframe
- We need to calculate the new keyframe selectors and approximate decimal values (e.g. the
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 like
@keyframes rainbowText {
from { color: red; }
via { color: orange; }
via { color: yellow; }
via { color: green; }
to { color: blue; }
}
Now, 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:
@keyframes fadeInRainbowTextFadeOut {
from { opacity: 0; }
25% { opacity: 1; color: red; }
via { color: orange; }
via { color: yellow; }
via { color: green; }
50% { opacity: 1; color: blue; }
to { opacity: 0; }
}
The via
keywords interpolate between the bounding absolute keyframe selectors (25%
and 50%
), so it would be equivalent to
@keyframes fadeInRainbowTextFadeOutSlow {
from { opacity: 0; }
25% { opacity: 1; color: red; }
31.25% { color: orange; }
37.5% { color: yellow; }
43.75% { color: green; }
50% { opacity: 1; color: blue; }
to { opacity: 0; }
}
This 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