Using Custom Properties to Wrangle Variations in Keyframe Animations
Have you ever wondered how to customize CSS animations keyframes without using any preprocessor feature, like mixins? I keep reaching for preprocessors for this reason, but it would so nice to drop yet one more dependency and go with vanilla CSS.
Well, I found a way to account for variations within a keyframe animation using nothing but CSS and it’s thanks to custom properties! Let’s learn a little more about how CSS keyframes work and how we can enhance them with CSS and a touch of custom properties.
Understanding CSS animations inheritance
When we assign an animation to an element, we can customize some of its properties such as duration, delay, and so on. Let me show you a dummy example: we have two classes: .walk
and .run
. Both share the same animation (named breath
) and .run
executes the animation faster than .walk
(0.5s
to 2s
, respectively).
@keyframes breath {
from {
transform: scale(0.5);
}
to {
transform: scale(1.5);
}
}
/* Both share the same animation, but walking is _slower_ than running */
.walk {
animation: breath 2s alternate;
}
.run {
animation: breath 0.5s alternate;
}
Each time we reuse an animation, it can behave differently based on the properties we assign it. So, we can say that an animation inherits its behavior based on the element where it’s applied.
But what about the animation *rules* (the scale in this case)? Let’s go back to the breath
animation example: The .walk
class executes breath
slower but it also needs to be deeper, so we need to change its scale value to be larger than it is for the .run
class, which takes smaller, more frequent breaths.
The common approach in plain CSS is to duplicate the original animation and tweak the values directly in the class:
@keyframes breath {
/* same as before... */
}
/* similar to breath, but with different scales */
@keyframes breathDeep {
from {
transform: scale(0.3);
}
to {
transform: scale(1.7);
}
}
.walk {
animation: breathDeep 2s alternate;
}
.run {
animation: breath 0.5s alternate;
}
While this works fine, there’s a better solution which allow us to reuse both the animation’s properties and its values! How? By taking advantage of CSS variables inheritance! Let’s see how:
/* breath behaves based on the
CSS variables values that are inherited */
@keyframes breath {
from {
transform: scale(var(--scaleStart));
}
to {
transform: scale(var(--scaleEnd));
}
}
.walk {
--scaleStart: 0.3;
--scaleEnd: 1.7;
animation: breath 2s alternate;
}
.run {
--scaleStart: 0.8;
--scaleEnd: 1.2;
animation: breath 0.5s alternate;
}
Cool, right? Now we don’t need to write duplicate animations to get varying effects from the same animation!
If you need to go even further, remember that we can also update CSS custom properties with JavaScript. Not only root variables, but also in specific elements. I find this incredible powerful because we can create more efficient animations by taking advantage of JavaScript without losing the native optimizations from CSS animation. It’s a win-win!
See the Pen
Dynamic CSS @keyframes w/ CSS Vanilla by Sandrina Pereira (@sandrina-p)
on CodePen.
The post Using Custom Properties to Wrangle Variations in Keyframe Animations appeared first on CSS-Tricks.