Articles

What Is the Web Animations API? JS-Native Animation

The Web Animations API lets JavaScript create and control animations natively, combining CSS-animation performance with imperative, scriptable control.

Takina Takina · · 3 min read
Close-up of code in an editor

The Web Animations API (WAAPI) is a browser-native JavaScript interface for creating and controlling animations, exposed through a single method — element.animate() — that returns an Animation object you can play, pause, reverse, and inspect from script. It sits deliberately between two older options: it runs with the same browser-optimized performance as CSS animations, but with the imperative, scriptable control that used to mean writing your own requestAnimationFrame loop.

The basic shape

animate() takes a set of keyframes and a timing configuration, and hands back a live Animation object:

const box = document.querySelector('.box');

const animation = box.animate(
  [
    { transform: 'translateX(0)', opacity: 1 },
    { transform: 'translateX(200px)', opacity: 0.5 },
  ],
  {
    duration: 400,
    easing: 'ease-out',
    fill: 'forwards',
  }
);

The keyframes array is functionally the same idea as a CSS @keyframes block, just expressed as JavaScript objects. The options object covers what a CSS animation shorthand would: duration, easing, delay, iteration count, direction, and fill (whether the animation’s end state persists once it finishes).

Controlling it after the fact

This is the part CSS animations can’t do without JavaScript hacks like toggling class names. The returned Animation object exposes methods and properties for live control:

animation.pause();
animation.play();
animation.reverse();
animation.playbackRate = 2;       // double speed
animation.finished.then(() => {  // a promise that resolves on completion
  console.log('animation done');
});

Because finished is a promise, sequencing animations — running one after another, or waiting for an animation to complete before updating application state — becomes a matter of await, not manually tracking animationend event listeners and matching them up with the right element.

Why not just use CSS animations

CSS animations and transitions are declarative and let the browser’s compositor handle the heavy lifting, which is why they stay smooth even under load — the same reason they’re the default recommendation in CSS transitions vs animations. What they don’t give you is fine-grained runtime control: you can’t easily pause a CSS animation partway through and query exactly how far along it is, reverse it cleanly, or change its playback rate on the fly. Getting that behavior with pure CSS usually means toggling classes and reading back computed styles — workable, but fragile.

WAAPI keeps the same compositor-driven performance characteristics as CSS animations (the browser can still run many of these animations off the main thread) while giving script the level of control that used to require requestAnimationFrame — the older approach of manually computing each frame’s state in a callback loop tied to the display’s refresh rate. requestAnimationFrame is still the right tool when an animation’s path genuinely depends on continuous input, like following a pointer or physics-based motion that can’t be expressed as a fixed set of keyframes. For everything with a defined start and end state that just needs to be interactively controllable, WAAPI is usually the simpler choice.

Comparing the three approaches

CSS animationsWeb Animations APIrequestAnimationFrame
Defined inStylesheetJavaScriptJavaScript
Runtime control (pause/reverse/rate)Limited, via class togglingNative — play/pause/reverse/rateFully manual
PerformanceCompositor-optimizedCompositor-optimizedDepends on your per-frame code
Best forStatic, declarative UI transitionsInteractive or JS-driven animations with a defined end stateContinuous, input-driven motion

Where it shows up in practice

Because WAAPI produces a standard Animation object, it composes cleanly with other browser APIs rather than requiring its own separate animation library for basic cases. The View Transitions API, for instance, is built on the same underlying animation model — a view transition is, under the hood, a set of pseudo-elements animated the same way element.animate() would animate them, which is part of why customizing a view transition’s timing uses familiar keyframe and easing concepts. WAAPI is also a natural fit for animating elements you’re already manipulating through the DOM in response to application state changes, since the same JavaScript that updates state can kick off and await the corresponding animation.

The takeaway

The Web Animations API gives JavaScript native, promise-based control over animations — play, pause, reverse, change speed, and await completion — while keeping the compositor-driven performance CSS animations are known for. Reach for it over CSS when an animation needs to be paused, reversed, or otherwise controlled at runtime in response to user interaction or application state; reach for requestAnimationFrame instead when the animation’s path can’t be expressed as a fixed set of keyframes at all. For most other UI motion, plain CSS transitions and animations remain the simplest option.

Takina Takina · · 4 min read

Object.groupBy() in JavaScript, Explained

Object.groupBy() buckets array items by a key you compute, replacing the reduce() boilerplate developers have written for years. How it works.

#JavaScript #Web Development #Frontend
Takina Takina · · 4 min read

Svelte 5 Runes Explained

Svelte 5 runes like $state and $derived replace the old reactive-assignment magic with explicit function calls that work anywhere in a file.

#JavaScript #Frameworks #Web Development