When to Use the Web Animations API

Firefox 48 is now available, and with it comes the third browser (after Chrome and Opera) to support an initial feature set of the Web Animations API. With it, Brian Birtles goes into detail why this API is a big deal. A few people have recently asked me why I talk so much about the API but still use CSS animations a lot of the time… so with Firefox’s official release, here are some thoughts on when using JS might make more sense than CSS.

But first, a spoiler… I still typically prefer CSS for animating. You state an animation once, and all matching selectors will pick up on it without you having to iterate through them all. There’s a reason over time we’ve seen things move from JS to CSS, and for me it’s hard to beat declaring some rules in CSS and calling it a day.

So Why Go with the API?

Dynamic/Random/New Values

One of the main reasons to reach for JavaScript is when values are not static. For a basic Transition, you can use JS to modify a value to a transition property dynamically in one line such as element.style.transitionDelay = '123ms' and that’s fine enough. However, modifying keyframe values on the fly is much more involved, such as adding a new stylesheet to the document with your new keyframes fully defined.

var frames = getFramesArray(); //get your new frames, e.g. [{offset: .5, transform: 'scale(1)'}]
animation = '@keyframes updatedAnimation {';
frames.forEach(function(frame) {
  animation += (frame.offset * 100) + '% {transform:' + frame.transform + '}';
});
animation += '}';

var style = document.createElement("style");
style.appendChild(document.createTextNode(animation));
document.head.appendChild(style);
var ele = document.getElementById('toAnimate');
ele.style.animationName = 'updatedAnimation';

Instead the API can handle this directly, and in one spot.

var frames = getFramesArray(); //get your new frames, e.g. [{offset: .5, transform: ''}];
var ele = document.getElementById('toAnimate');
ele.animate(frames, 1000);

Making randomized confetti, snow, and springy objects often requires less tinkering when using the API.

See the Pen Confetti by Dan Wilson (@danwilson) on CodePen.

For the confetti demo I actually combined both WAAPI and CSS. I used the WAAPI to generate random scale and horizontal placement values (also duration and negative delays), while animating inner divs with a 3D rotation and a wavering back and forth via CSS. I could have taken it further and animated everything with random values, but having only the container based on random values (for the primary confetti action of falling to the ground) was enough for it to feel spontaneous.

And yes, I agree - the phrase “primary confetti action” is one of the least confetti-related phrases a person can say.

A Plethora of Class Toggles

If you’re already doing a lot of logic to add and remove classes to trigger your CSS transitions or animations, the API might be a good way to go as well. That way all of your logic is in one place instead of two. Especially, if you are also needing to listen to animation events like animationend or transitionend. That is usually a sign to me that the only reason I’m using CSS is to take advantage of hardware acceleration (which you will get from browsers that support the WAAPI already).

See the Pen 755de1ba31b1629e4f662db0818185ac by Dan Wilson (@danwilson) on CodePen.

Playback Control

When you want to change the rate or be able to jump to different frames, the API will be the easiest way to do that now. It’s all technically achievable with CSS now, but you have to take a fair amount of extra care to get timings right.

Chaining Multiple Animations

Another reason is if you have complex animations that depend on other animations for when to start. The next level of the spec is introducing formal grouping and sequencing for multiple animations, but even now using the callbacks, delay, and endDelays in the WAAPI can be a lot easier than managing your sequence of animations via delays alone in CSS.

An excellent CSS-Tricks article comparing various animation methods (by Sarah Drasner) covers the cons for CSS in detail.

What about Some Specifics

See the Pen Falling Letters by Dan Wilson (@danwilson) on CodePen.

I’ve used the Web Animations in a couple client projects because they were basic enough, but still benefited from the playback rate and timeline control.

You can also use features like canceling, playbackRate variance, dynamic elements/values, onfinish handlers, and more to create a game. The CodePen version of a game I recently created is shown here, with the full version now at Letters and Such. Effectively, letters (or other characters) fall, and you have to type the appropraite key before they reach the ground. Playback Rate is increased over time, letters and locations are randomized, and if the correct key is typed the animation is canceled (and you get a point, to boot). If the key is not pressed in time, however, the onfinish handler will be called and a “miss” is counted. The code in the CodePen is commented as far as the logic is concerned, so take a look for more detail.

There is nothing that would prevent you from making this with CSS animations. It made sense for me to keep the animations primarily in JS, especially since the animations drive a lot of the actual game logic.

But What about the Future?

The Web Animations spec that underlies the Web Animations API is all about uniting JS and CSS methods. Firefox Nightly builds actually allow you to get all Animations on the document via JS, whether generated with the WAAPI, CSS Animations, or CSS Transitions. Right now some of the properties on CSS ones are read only (no changing of duration, for example), but already you can read/write the currentTime, pause these animations, or change playbackRate. There will be even less to differentiate the methods beyond personal preference as the spec matures.