Animating from JavaScript
element.animate()
Baseline widely available
Chrome84
Edge84
Firefox75
Safari14
Features it needs
- Web animationsWidely available
These libraries run their own tick loop, working out each frame's values in JavaScript and writing them to the element's style. element.animate() hands the same keyframes to the engine that already runs CSS animations, so transforms and opacity are animated off the main thread and keep going while JavaScript is busy. It returns an Animation with play, pause, reverse, cancel and finish on it, plus a finished promise to await.
When this applies
Animating an element's styles from JavaScript and needing a handle to control it.
The native approach
const animation = card.animate(
[
{ transform: "translateY(12px)", opacity: 0 },
{ transform: "none", opacity: 1 },
],
{ duration: 240, easing: "cubic-bezier(0.2, 0, 0, 1)", fill: "both" },
);
await animation.finished;
// The same handle drives it afterwards.
animation.reverse();When the dependency is still right
An answer that always says "the platform covers it" is worse than no answer. These are the cases where this one does not hold.
- You animate something that is not a CSS property on an element: a number in a counter, a canvas, a scroll offset, an SVG path's shape. anime.js animates arbitrary object properties, where element.animate() only writes styles.
- The motion is spring-based or driven by a gesture's velocity. Web Animations takes a duration and an easing curve, so anything that has to respond to how fast a finger was moving is still the library's job.
- You sequence many elements on one timeline with staggers and relative offsets. That timeline is the reason a lot of people install anime.js, and composing it by hand means computing every delay yourself.
- A plain CSS transition or @keyframes would do. Reaching for element.animate() to fade one element in trades a declarative rule for a script that has to run first.
- You animate to an intrinsic size such as height: auto, which is interpolate-size and calc-size rather than either approach here.