Reusable @keyframes with CSS custom properties

j3nnning

Jenning Ho

Posted on January 13, 2020

Reusable @keyframes with CSS custom properties

In this article, I will share with you an application of CSS custom properties that I have found useful.

If you're like me, who like to cramp as many animations in the page as possible for micro interactions sake (just kidding, don't do that), you would be writing a lot of CSS animations with @keyframes.

@keyframes is notorious for its inflexibility, once it is declared, the values are then set in stone. If you have a set of @keyframes with the same behavior but different values, you'll need to make another set. This result in a lot of @keyframes that are similar but with a little variations in the numbers. Let’s take a look at the example below:

@keyframes fade-in {
  0% {
    opacity: 0;
  }

  100% {
    opacity: 1;
  }
}

@keyframes fade-in-a-little {
  0% {
    opacity: 0;
  }

  100% {
    opacity: 0.3;
  }
}

.item-1 {
  animation: fade-in 300ms ease;
}

.item-2 {
  animation: fade-in-a-little 300ms ease;
}
Enter fullscreen mode Exit fullscreen mode

In the example above, we have 2 items with 2 different animations that are similar, with only slight difference in the opacity value at 100%.

Now imagine what this would turn into when applied to more items. As the website scale up, what you'll end up with is 100s of similar @keyframes, bloating up the CSS file. We can't have that. 😐

CSS custom properties to the rescue

CSS custom properties (also known as CSS variables), are most widely applied for theming. It can also be used to make @keyframes reusable! (If you want to learn about CSS custom properties, see here)

Let's refactor our previous example with CSS custom properties!

@keyframes fade {
  0% {
    opacity: var(--fade-start, 0);
  }

  100% {
    opacity: var(--fade-end, 1);
  }
}

.item-1 {
  animation: fade 300ms ease;
}

.item-2 {
  --fade-end: 0.3;
  animation: fade 300ms ease;
}
Enter fullscreen mode Exit fullscreen mode

fade-in-a-little @keyframes is taken out as it is not needed anymore. We now have only 1 set of @keyframes fade, and apply CSS custom properties to the starting opacity value and the ending opacity value with:

opacity: var(--fade-start, 0); // start

opacity: var(--fade-end, 1); // end
Enter fullscreen mode Exit fullscreen mode

In this example, we have 2 custom properties: --fade-start and --fade-end. These variables are applied using var() function (read more about it here). The var() function accepts 2 parameters, a value and a fallback (default value).

So with this line opacity: var(--fade-start, 0);, if --fade-start is not set, 0 will be applied instead. The same goes to --fade-end.

The end result we get here is a set of @keyframes that can fade between opacity: 0 and opacity: 1 by default and be tuned within the scope of a CSS selector. 🤯

Wait... so to fade out? Yes! Instead of declaring another set of @keyframes for fade-out, you can reuse fade and set --fade-start as 1, and --fade-end to 0, like so:

.item-to-fade-out {
  --fade-start: 1;
  --fade-end: 0;
  animation: fade 300ms ease;
}
Enter fullscreen mode Exit fullscreen mode

With CSS custom properties, @keyframes can now be function like, where the variable parts can be defined at a later stage, making @keyframes reusable. Yay DRY ❤️️

Time to bust out the Codepen

One @keyframes to fade it all

Summary

Fading animation is one of the most common animation on the web, now with CSS custom properties we can reduce our CSS bloat significantly while having as many variations of it as we'd like.

Consider applying this to @keyframes that you find yourself repeating a lot with many little variations.

Hope you'll find this useful!

💖 💪 🙅 🚩
j3nnning
Jenning Ho

Posted on January 13, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related