When should you use CSS for animations? When should you use JavaScript for animations? Is one better than the other?
Should you always try to use CSS to animate your components as much as you can? What about “hardware acceleration”?
These questions ran through my head as I learned to animate websites. When I first started, I read so much about “hardware acceleration” and downsides of using JavaScript that I focused entirely on CSS for all my animations.
I actively avoided JavaScript because I thought JavaScript animations didn’t perform well. Besides, I didn’t want to be that guy that doesn’t provide a good experience for people who don’t have JavaScript.
I only realised much later that I made my life insanely difficult by avoiding JavaScript. To make things worse, I created inaccessible websites while trying to avoid JavaScript altogether.
So, I learned that you can use both CSS and JavaScript to create animations. The question is when to use which.
Creating silky smooth animations
If you have the misconception that JavaScript can’t be used to produce smooth animations, you can drop it now. Both CSS and JavaScript can be used to produce silky smooth animations. You don’t need everything to be “hardware-accelerated”.
Why is that so?
Many computers refresh at a rate of 60 frames per second. For your animations to be smooth, the browser needs to update your animation within this rate. In other words, browsers need to update your website at least once every 16 milliseconds (ie once every 60th of a second).
So, your job is to make sure you don’t create animations that require browsers to do so much work that it can’t update the screen within 16 milliseconds.
To ensure the browser doesn’t do extra hard work, you should only change the following four properties. (Find out why in Paul Lewis’ and Paul Irish’s article on High Performance Animations). It doesn’t matter whether you change them with CSS or JavaScript.
- Translate (from the
transform
property) - Rotate (from the
transform
property) - Scale (from the
transform
property) - Opacity
With performance-related questions out of the way, let’s focus on when to use CSS/JavaScript for your animations.
Animating with CSS and JavaScript
There are three ways you can create animations:
- With CSS transitions
- With CSS animations
- With JavaScript
When to use CSS transitions
CSS transitions allow you to change CSS properties between two states — the beginning state and the end state.
To use CSS transitions, you specify the properties you want to animate with the transition
property.
button {
background-color: turquoise;
transition: background-color 0.3s ease-out;
}
button:hover {
background-color: pink;
}
Changing a button’s background-color
property from turquoise to pink.
You can also transit properties with the help of JavaScript. To do so, you can either change the property directly, or add/remove a class to/from the element.
// Changing a CSS property
button.style.backgroundColor = 'blue'
// Adding a class
button.classList.add('is-selected');
// Removing a class
button.classList.remove('is-selected');
CSS transitions are best for simple animations that contains only two states. When you need to animate something over multiple different states, you might want to consider CSS animations or JavaScript.
When to use CSS animations
CSS animations allow you to animate any CSS property through any number of states. You can even use it to create a slightly-more-complicated animation like this hand-waving animation:
A multi-state hand waving animation.
To create a CSS animation, you specify the properties you want to animate with the animation
property, and you declare your animation with @keyframes
.
/* Declaring the animation */
@keyframes swing {
0% {
transform: translateX(-3em);
}
100% {
transform: translateX(0);
}
}
/* Specifying the animation */
button {
animation: swing 1s ease-in-out infinite alternate;
}
Animation of a button swinging left and right.
To create the hand-waving animation, you first have to code all six possible states into your @keyframes
declaration. It looks like this:
Six different states for the hand.
@keyframes wave {
0% { transform: rotate(0); }
20% { transform: rotate(15deg); }
40% { transform: rotate(-15deg); }
60% { transform: rotate(15deg); }
80% { transform: rotate(-15deg); }
100% { transform: rotate(0); }
}
.wave-hand {
transform-origin: bottom center;
animation: wave 1s ease-in-out infinite;
}
Notice the percentages like 0%
and 40%
in the @keyframes
syntax above? These percentages indicate the CSS values to display on your site at that completion rate.
Let’s say you have an animation that lasts two seconds. A 50%
would mean the one-second mark while 75%
would mean the one-and-a-half-second mark. If your animation lasts four seconds, 50%
would mean the two-second mark, while 75%
would mean the three-second mark.
When you first code your animation, you will likely not be able to correctly identify your animation duration between each state, so you’ll have to recalculate the percentages a couple of times. It’s a chore.
For this reason, I highly recommend you use JavaScript animation libraries to give yourself a better experience when creating animations.
The only exception is when you need your animations to run without JavaScript — then CSS animations are preferred.
When to use JavaScript
Well, you probably have a good idea by now — when you have an animation that’s complex (which means you can’t use CSS transitions, and it’s hard to use CSS animations), you’ll want to use JavaScript.
When you use JavaScript to animate, you change the value of a CSS property over time. This process can be done manually (you calculate and set the value of a CSS property at every frame) or through a JavaScript library (like the Greensock Animation API).
If you inspect the console, you’ll see how quickly JavaScript updates the CSS property (in this case, transform
).
JavaScript updates the transform property over time.
If you’ve been keeping up with the latest developments, you’ll also know you can create animations through the Web Animations API, which means you don’t need to use an external animation library.
Sadly, at the time of writing, the Web Animations API is still not ready for prime time.
Support for Web Animations API is still lackluster at this point.
When you create animations with JavaScript, I highly recommend you use the Greensock Animation API (GSAP). It’s the fastest and most well-supported library out there. There’s an introductory tutorial to help you get started with GSAP on my site.
If you want inspiration of things built with GSAP, you can check out Sarah Drasner’s and Chris Gannon’s CodePens. They’re amazing.
But what if people don’t have JavaScript?
When would you animate things? Think about this question for a moment.
Usually, you either animate things right when the page loads, or when a user interacts with a specific element on your page (like click a button).
If you need to animate things when your page loads, you can rely on CSS animations. No worries about that.
If you need to animate things when a user interacts with elements on your page, you can’t run away from JavaScript.
Why?
You can only tell if a user has interacted with an element if you’ve added an event listener to the document/element. Adding an event listener requires JavaScript, so most of your animations (CSS transitions or otherwise) wouldn’t work without JavaScript anyway.
Then, the question isn’t about supporting animations for users without JavaScript. They simply don’t get any animations from their interactions.
So what you should do is to make sure your site works well without animation. Your users should be able to see what they came to your site for — your content — even without JavaScript turned on.
When users with JavaScript come to your site, you can give them an enhanced experience with animations. Be liberal with your use of JavaScript here.
This is a concept called progressive enhancement. If you’d like to find out more it, you can follow Aaron Gustafson, listen to this episode of The Web Ahead podcast, or read Aaron’s evergreen article Understanding Progressive Enhancement on A List Apart.
Wrapping up
You can use CSS and JavaScript to create animations. What you use depends on the complexity of the animation.
For simple two-state animations, I recommend you use CSS transitions. For more complicated animations, I recommend you use CSS animations or JavaScript.
At the time of writing, the Web Animations API is still not well supported yet, so the best possible way to animate is with GSAP, which is an amazing library.
Make sure you provide a non-animated, but workable version of your site for people who don’t have JavaScript enabled. They should still be able to use your website even when it’s not animated.
If you found this article helpful and would like to read more articles like this one, feel free to pop over to my website.
You may also like Learn JavaScript — a course that helps you learn to build real components from scratch with JavaScript.
Comments
Please remember that all comments are moderated and any links you paste in your comment will remain as plain text. If your comment looks like spam it will be deleted. We're looking forward to answering your questions and hearing your comments and opinions!