Three tools: CSS, the Web Animations API, GSAP
There are three main ways to animate in the browser.
- CSS (
transition,@keyframes) - hover, appearance and simple effects. Little code, and the browser optimizes it. - Web Animations API (
element.animate()) - the power of CSS, but controlled from JS:pause(),reverse(),finished. - GSAP - complex sequences,
timeline,ScrollTrigger, precise control, the same behavior across browsers.
Most of the time you do not need GSAP. CSS is enough for a button hover; add the library when you need sequences and scroll scenes.
| Tool | Strength | Limit |
|---|---|---|
| CSS | Simple, no code, browser-optimized | Hard to sequence and control |
animate() | JS control, finished, reverse | No timeline or scroll scenes |
| GSAP | timeline, ScrollTrigger, stagger, precision | An extra dependency, bundle size |
CSS animations
transition moves between two states (for example on hover). @keyframes describes a multi-step animation and is attached with animation. The code below ends with a prefers-reduced-motion block: it is worth writing once for the whole project.
.card {
transition: transform 0.3s ease, opacity 0.3s ease;
}
.card:hover {
transform: translateY(-4px);
}
@keyframes fade-up {
from { opacity: 0; transform: translateY(24px); }
to { opacity: 1; transform: none; }
}
.hero {
animation: fade-up 0.6s ease-out both;
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}💡 The
bothvalue ofanimationkeeps the first frame before the start and the last frame after the end.
The Web Animations API
element.animate(keyframes, options) works like a CSS animation but returns an Animation object. With it you can pause the animation, change its speed, play it backwards and wait for the end through the finished promise.
const box = document.querySelector('.box');