Should you use CSS or JavaScript for web animations? | Heart Internet Blog – Focusing on all aspects of the web

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.

  1. Translate (from the transform property)
  2. Rotate (from the transform property)
  3. Scale (from the transform property)
  4. 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:

  1. With CSS transitions
  2. With CSS animations
  3. 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;
}

Animated GIF where a Click Here button changes from turquoise to pink when hovered over
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:

Animated GIF of a hand waving
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;
}

Animated GIF of a Click Me button sliding from left to right
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 to set up the animation
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).

Animated GIF showing how the JavaScript updates the CSS property for the Click Me button
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.

Image listing the browser support for the Web Animations API
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!

Got a question? Explore our Support Database. Start a live chat*.
Or log in to raise a ticket for support.
*Please note: you will need to accept cookies to see and use our live chat service