What Is the Web Animations API and How Does It Compare to CSS Animations?
Learn how the Web Animations API works, its playback controls, and when to use it over static CSS keyframe animations.
Expected Interview Answer
The Web Animations API (WAAPI) is a JavaScript interface, exposed via element.animate(), that lets you define and control keyframe animations programmatically with the same browser-native, off-main-thread performance as CSS animations, while giving you play, pause, reverse, and dynamic-timing control that plain CSS cannot offer.
Calling element.animate(keyframes, options) returns an Animation object with a playback-control interface β play(), pause(), reverse(), finish(), and a currentTime you can scrub directly β all run by the browser compositor rather than JavaScript timers, so performance matches hand-written CSS @keyframes. This makes WAAPI the natural choice when animation parameters depend on runtime data (drag distance, a fetched value, user input) that cannot be baked into a static stylesheet, or when you need to sequence, chain, or synchronize animations, listen for the finished promise, or read/scrub playback state. CSS animations remain simpler for fixed, declarative effects defined entirely in a stylesheet and are easier for designers to author and tweak without touching JavaScript. In practice, teams use CSS for static, decorative motion and WAAPI for interactive or data-driven animation that needs imperative control, and WAAPI keyframes can even be extracted from existing CSS animations via getAnimations() for introspection or coordination.
- Runs on the browser compositor for the same smooth performance as CSS
- Exposes play, pause, reverse, and scrubbable currentTime programmatically
- Lets animation parameters be computed dynamically from runtime data
- Provides a finished Promise and getAnimations() for sequencing and introspection
AI Mentor Explanation
CSS animations are like a pre-recorded highlights reel of a six being hit, always playing the exact same sequence from start to finish once triggered. The Web Animations API is like a broadcast director with a live control desk who can pause the replay mid-flight, reverse it to check the bowler run-up, or scrub to the exact moment of contact on demand. Both use the same underlying camera feed for smooth playback, but only the directorβs desk lets you react to what the umpire calls in real time. That extra runtime control, without losing playback smoothness, is exactly what WAAPI adds over static CSS keyframes.
Step-by-Step Explanation
Step 1
Select the element
Get a reference to the DOM element you want to animate.
Step 2
Call element.animate()
Pass an array of keyframe objects and a timing options object (duration, easing, iterations).
Step 3
Receive the Animation object
The returned Animation exposes play, pause, reverse, finish, currentTime, and playbackRate.
Step 4
React to state or completion
Await animation.finished (a Promise) or listen for the finish event to sequence follow-up work.
What Interviewer Expects
- Understands WAAPI runs on the compositor, matching CSS animation performance
- Can articulate when to prefer WAAPI (dynamic/data-driven) over CSS (static/declarative)
- Knows the Animation object playback-control surface (play/pause/reverse/currentTime)
- Mentions getAnimations() and the finished Promise for sequencing
Common Mistakes
- Assuming WAAPI is slower than CSS because it is JavaScript-driven
- Reaching for WAAPI for every animation instead of simple, static CSS keyframes
- Forgetting to handle the finished Promise, causing animation chains to desync
- Not knowing you can inspect running CSS animations via getAnimations()
Best Answer (HR Friendly)
βThe Web Animations API lets you control animations from JavaScript with play, pause, and reverse, while still getting the same smooth performance as CSS animations because the browser runs them the same efficient way. I would reach for it when an animation depends on live data or user interaction, and stick with plain CSS for simple, fixed effects.β
Code Example
const card = document.querySelector('.card')
const animation = card.animate(
[
{ transform: 'translateX(0)', opacity: 1 },
{ transform: `translateX(${dragDistance}px)`, opacity: 0.4 },
],
{ duration: 300, easing: 'ease-out', fill: 'forwards' }
)
pauseButton.addEventListener('click', () => animation.pause())
resumeButton.addEventListener('click', () => animation.play())
animation.finished.then(() => {
card.remove()
})Follow-up Questions
- When would you choose the Web Animations API over CSS @keyframes?
- How does getAnimations() let you inspect animations defined purely in CSS?
- How would you synchronize two separate WAAPI animations to finish together?
- What is the performance difference between compositor-driven and JS-timer-driven animation?
MCQ Practice
1. What does element.animate() return?
element.animate() returns a live Animation object exposing imperative playback control.
2. Why does WAAPI typically match CSS animation performance?
Both APIs hand animation work to the compositor, so their frame performance is comparable.
3. When is WAAPI generally preferred over static CSS animations?
WAAPI shines when keyframes or timing must be computed dynamically at runtime.
Flash Cards
How do you start a WAAPI animation? β element.animate(keyframes, options), which returns an Animation object.
Why is WAAPI as fast as CSS? β Both run on the browser compositor, not JavaScript timers.
When to prefer WAAPI over CSS? β When timing/keyframes depend on runtime data or need imperative control.
How do you know a WAAPI animation finished? β Await the animation.finished Promise or listen for the finish event.