W3docs

Web Animations API

Learn how to use the Web Animations API to create and control animations directly from JavaScript with programmatic control and hardware acceleration.

The Web Animations API

The Web Animations API (WAAPI) lets you create and control animations directly from JavaScript, with no external library. It runs animations on the browser's own compositor — the same engine that powers CSS animations — so you get smooth, hardware-accelerated motion, but with the programmatic control of JavaScript animations: you can play, pause, reverse, speed up, seek, and chain animations at runtime.

This page covers the two pieces you need: the element.animate() method that starts an animation, and the Animation object it returns, which you use to control playback and to know when the animation finishes.

element.animate(keyframes, options)

Every WAAPI animation starts with one call:

const animation = element.animate(keyframes, options);
  • keyframes — the visual states to move through. Two shapes are accepted:
    • an array of objects, where each object is one frame: [{ opacity: 0 }, { opacity: 1 }]
    • an object of arrays, where each property lists its values across the timeline: { opacity: [0, 1] }
  • options — either a number (the duration in milliseconds) or a timing object such as { duration: 1000, easing: "ease-in-out", fill: "forwards" }.

The call returns an Animation object and starts playing immediately. Property names use the camelCased CSS form (backgroundColor, not background-color).

Basic Animation with Web Animations API

Creating a basic animation with the Web Animations API involves defining the animation's keyframes, specifying the target element, and configuring the animation options. Here's a simplified example of animating an element's opacity:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Simple Opacity Animation</title>
  </head>
  <body>
    <h1>Simple Opacity Animation</h1>
    <div
      class="animated-element"
      style="width: 100px; height: 100px; background-color: blue"
    ></div>
    <button style="margin-top: 15px" onclick="startAnimation()">
      Start Animation
    </button>
    <p id="message"></p>
    <script>
      let animation;

      function startAnimation() {
        const element = document.querySelector(".animated-element");
        const keyframes = [
          { opacity: 0, offset: 0 },
          { opacity: 1, offset: 1 },
        ];
        const options = {
          duration: 1000,
          easing: "ease-in-out",
          iterations: 1,
          fill: "forwards",
        };

        // Create and play the animation
        animation = element.animate(keyframes, options);

        // Handle animation events
        animation.onfinish = () => {
          document.getElementById("message").textContent =
            "Animation finished!";
        };

        animation.oncancel = () => {
          document.getElementById("message").textContent = "Animation reset.";
        };
      }

      // Resets the animation
      function resetAnimation() {
        if (animation) {
          animation.cancel();
        }
        startAnimation(); // Restart the animation
      }
    </script>
  </body>
</html>

This example demonstrates how to animate the opacity of an element using the Web Animations API. A button triggers the animation, which smoothly changes the element's opacity from invisible (0) to fully visible (1). After the animation completes, a message is displayed to the user. This illustrates basic animation control and event handling.

Timing options

The second argument to animate() controls how the animation runs over time. The most useful keys are:

OptionWhat it does
durationLength of one iteration, in milliseconds (or a CSS time string like "1s").
iterationsHow many times to repeat. Use Infinity to loop forever.
easingThe acceleration curve: "linear", "ease", "ease-in-out", or a cubic-bezier(...).
fillWhat state to keep outside the active range. "forwards" holds the last frame; "backwards" applies the first frame during delay; "both" does both.
delayMilliseconds to wait before starting.
direction"normal", "reverse", or "alternate" (bounce back and forth on each iteration).

Without fill: "forwards", an element snaps back to its original styles the instant the animation ends — a common source of confusion. Set it when the final frame should stick.

The Animation object

element.animate() returns an Animation instance. This is the handle you use after the animation has started:

MemberPurpose
play()Start or resume playback.
pause()Freeze at the current point.
reverse()Run from the current point back toward the start.
finish()Jump straight to the end (or start, if reversed).
cancel()Stop and remove all effects, clearing applied styles.
finishedA Promise that resolves when the animation completes — ideal for sequencing with await.
playState"running", "paused", "finished", or "idle".
playbackRateSpeed multiplier; 2 is double speed, -1 plays backward.
const anim = box.animate({ transform: ["translateX(0)", "translateX(200px)"] }, 1000);

anim.pause();          // hold in place
anim.playbackRate = 2; // play twice as fast when resumed
anim.play();

anim.finished.then(() => console.log(anim.playState)); // "finished"

Because finished is a real Promise, you can await it to run code only after the motion ends, or to chain animations cleanly — as the next example does.

Complex Animations and Sequences

For more complex animations and sequences, you can chain multiple animations together using promises and async/await. Here's an example of chaining animations:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Animation Sequence</title>
  </head>
  <body>
    <h1>Animation Sequence</h1>
    <div
      class="animated-element"
      style="width: 100px; height: 100px; background-color: red"
    ></div>
    <button style="margin-top: 15px" onclick="animateSequence()">
      Start Animation
    </button>
    <p id="message"></p>
    <script>
      async function animateSequence() {
        document.getElementById("message").textContent = ""; // Clear message
        const element = document.querySelector(".animated-element");
        const animation1 = element.animate(
          { opacity: [0, 1], transform: ["scale(0)", "scale(1)"] },
          { duration: 1000, easing: "ease-in-out" }
        );

        await animation1.finished;

        const animation2 = element.animate(
          { opacity: [1, 0], transform: ["scale(1)", "scale(0)"] },
          { duration: 1000, easing: "ease-in-out" }
        );

        await animation2.finished;
        document.getElementById("message").textContent = "Sequence complete!";
      }
    </script>
  </body>
</html>

In this example, the first animation increases the element's opacity and scales it up, and upon completion, the second animation fades the element out and scales it down. A completion message is displayed at the end, demonstrating how to chain animations sequentially.

Controlling and Managing Animations

The Web Animations API also provides methods for controlling and managing animations. For instance, you can pause, resume, or cancel an animation. Here's an example of how to pause and resume an animation:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Toggle Animation Play/Pause</title>
  </head>
  <body>
    <h1>Toggle Play/Pause Animation</h1>
    <div
      class="animated-element"
      style="width: 100px; height: 100px; background-color: green"
    ></div>
    <button style="margin-top: 15px" onclick="togglePlayPause()">Toggle Play/Pause</button>
    <p id="message"></p>
    <script>
      let animation;

      document.addEventListener("DOMContentLoaded", function () {
        const element = document.querySelector(".animated-element");
        animation = element.animate(
          { opacity: [0, 1] },
          { 
            duration: 1000, 
            easing: "ease-in-out", 
            iterations: Infinity, 
            direction: "alternate" 
          }
        );
        animation.pause(); // Start paused

        animation.onfinish = () => {
          document.getElementById("message").textContent =
            "Animation finished!";
        };
      });

      function togglePlayPause() {
        if (animation.playState === "running") {
          animation.pause();
          document.getElementById("message").textContent = "Animation paused";
        } else {
          animation.play();
          document.getElementById("message").textContent = "Animation playing";
        }
      }
    </script>
  </body>
</html>

This example shows how to toggle the play and pause states of an animation with a click. The initial animation makes an element fade in and out continuously. Clicking a button allows the user to pause the animation if it's running, or play it if it's paused. Messages indicate the current state of the animation, enhancing user interaction and control over animation states.

Web Animations API vs CSS animations

Both run on the same compositor, so performance is comparable. The difference is control:

  • Reach for CSS animations when the motion is declarative and static — a hover effect, a loading spinner, an entrance transition you can define entirely in a stylesheet.
  • Reach for the Web Animations API when the animation depends on runtime data or user input: dynamic keyframe values, pausing and resuming on demand, sequencing several animations, or reacting to when one finishes via the finished promise.

A handy middle ground is to keep your styling in classes — see Styles and classes — and use WAAPI only for the transitions that need scripted control.

Conclusion

The Web Animation API empowers web developers to create captivating and interactive animations that enhance the user experience on websites and web applications. By mastering this API, you can craft animations ranging from simple transitions to complex sequences, adding a dynamic and engaging dimension to your web designs. Whether you're animating user interfaces, adding visual effects, or creating interactive storytelling elements, the Web Animations API provides the tools you need to bring your creative ideas to life on the web.

Practice

Practice
What functionalities does the JavaScript Animation API offer?
What functionalities does the JavaScript Animation API offer?
Was this page helpful?