A Guide to CSS Animation - Part 3
Tags: css, animation, beginners, webdev
Published: 2019-12-20 18:23:03

> Let's do some cool stuff 😎

If you’ve made it this far, you now know pretty much all you need to know about CSS animations. Pat yourself on the back 🙌

This final part won’t be long but I didn’t want to cram it into the other parts. In this part we take a look at some bonus topics 👍 It’s a bit of a mix but some things to consider and be knowledgeable of.

As with parts [1](https://dev.to/jh3y/a-guide-to-css-animation-part-1-36o9) and [2](https://dev.to/jh3y/a-guide-to-css-animation-part-2-2hjo), all code is available in the CodePen collection. This gives you a way to play around with the code 🎾

[![Link to CodePen collection of demos](https://thepracticaldev.s3.amazonaws.com/i/jqssaberzcdexpoqwzce.png)](https://codepen.io/collection/nMpBQm/)

# CSS Variables

CSS variables are awesome. But we can’t animate the values yet. So what can we do with them? We can use their values to create dynamic animations.

Consider an example where we have three squares. We want to animate them all growing to different scales. Do we need three different animations for this? We could use `animation-fill-mode` `backwards` and scale them all from the same start size? But do we know their start size? With CSS variables we can make the animation dynamic.

How about the following code

```css
div {
  animation: change 0.5s cubic-bezier(1, 0.2, 0.6, 1.75) 1s forwards;
}
div:nth-of-type(1) {
  --scale: 1.2;
}
div:nth-of-type(2) {
  --scale: 2.6;
}
div:nth-of-type(3) {
  --scale: 1.8;
}
@keyframes change {
  to {
    transform: scale(var(--scale));
  }
}

```

{% codepen https://codepen.io/jh3y/pen/rKMgQO %}


Before, it was the case that you couldn't update an animation at run time by changing CSS variable values. The trick in this scenario would be to flip the animation on its head. Consider this example.

{% codepen https://codepen.io/jh3y/pen/QxKXEW %}

But, now animations do respond to changing CSS variables. Recently I tweeted this.

{% twitter 1191695646752948225 %}

Containing this demo. 

{% codepen https://codepen.io/jh3y/pen/zYYWxGZ %}

In this demo, we actually update the animation values at run time by changing the value of a CSS variable 😲

# Curved animation path
So we can animate an element from point to point but how do we add a curve to our animation path?

Let’s start with a simple example where we want an element to travel from one point to another but get some air time.

```css
div {
  animation: throw 2s ease 1s both;
}
@keyframes throw {
  0% {
    transform: translate(-25vw, 0);
  }
  50% {
    transform: translate(0, -20vh);
  }
  100% {
    transform: translate(25vw, 0);
  }
}
```

Looks good. But it won’t work. We will get something like this

{% codepen https://codepen.io/jh3y/pen/wvBJeeZ %}

So how do we combat that? We need two animations and two elements. The wrapper element will handle the X-axis. The actual element will handle the Y-axis.

```css
.wrapper {
  animation: x 2s ease-in-out infinite 1s both;
}

.wrapper > div {
  animation: y 2s ease-in-out infinite 1s both;
}

@keyframes x {
  0% {
    transform: translate(-25vw, 0);
  }
  100% {
    transform: translate(25vw, 0)
  }
}

@keyframes y {
  50% {
    transform: translate(0, -20vh);
  }
}
```

{% codepen https://codepen.io/jh3y/pen/YvGmXo %}

Sweet 🍭

And here’s a little loader you could put together with this technique 🐛

{% codepen https://codepen.io/jh3y/pen/JZbxZG %}

There is another technique for CSS animation along a curved path. If you're familiar with SVG path notation, it might be worth checking out 👍 Support isn't brilliant yet but the docs are [here](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Motion_Path).

-------------

# JavaScript hooks
So what if we need to know when an animation has ended in our JavaScript? Don’t worry. There are some events we can hook into.

- `animationiteration` - triggered after each animation iteration
- `animationend` - triggered after an animation completes
- `animationstart` - triggered at the start of an animation

These hooks are pretty powerful and allow us to do some pretty cool things. Consider an infinitely spinning element. Using `animationiteration` we can keep a track of how many times the element has span for example.

```javascript
const spinner = document.querySelector('div')
const label = document.querySelector('h1')
let span = 0
const update = () => {
  span++
  label.innerText = `Span ${span} times!`
}
spinner.addEventListener('animationiteration', update)
```

{% codepen https://codepen.io/jh3y/pen/QxKeJQ %}


There are many possibilities when you start hooking into the animation events. You could also make an animation infinite but with random delays.

{% codepen https://codepen.io/jh3y/pen/yEVBYG %}

# Do you even need CSS animation?

If you’ve got this far, we pretty much know everything there is to know about CSS animation 🙌

It might seem like an odd topic to end on but do you even need CSS animation? 😕

Hear me out. CSS animation is great. But once your animations start becoming complex, things get harder to maintain.

You can make use of the JavaScript hooks to manage things a little better. But if you start developing complex timelines, don’t start reinventing the wheel. There are great tools out there to aid with animation. I can’t vouch for [GreenSock(GSAP)](https://greensock.com/) enough. It’s brilliant for gaining complete control over your animations from the `JavaScript` side.

[![Link to GreenSock docs](https://thepracticaldev.s3.amazonaws.com/i/i5guq3cuie69dg9h9pv2.png)](https://greensock.com)

So why learn CSS animation at all?! CSS animation still has a place. There are plenty of things you can do with it. And you might not always be able to rely on `JavaScript`. Especially if a user has it disabled in their browser. Consider simpler things that you might animate such as loading spinners and micro-interactions. These still contribute to user experience.

---------

# That’s it! 🎉
If you’ve got this far, thank you so much for sticking around!

You should be all set now to go off and get things moving 📽 If there’s something you are not quite sure about or feel could be explained better, don’t hesitate to reach out. I'd be eager to hear your feedback 👍

All of the demos are available in the following CodePen collection 👍

[![Link to CodePen collection of demos](https://thepracticaldev.s3.amazonaws.com/i/jqssaberzcdexpoqwzce.png)](https://codepen.io/collection/nMpBQm/)

As always, any questions or suggestions, please feel free to leave a response or [tweet me 🐦](https://twitter.com/@jh3yy)! Be sure to connect with me on the socials! 😎