Should you use CSS or JavaScript for web animations?

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.

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.

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.

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.