How CSS animations work
A CSS animation has two parts. An @keyframes rule describes what changes — the styles at from/to or at percentage points along the timeline — and the animation property on an element says how to play it: which keyframes, for how long, with which easing, how many times and in which direction. Unlike transitions, animations run without a state change and can loop.
The animation shorthand accepts name duration timing-function delay iteration-count direction fill-mode play-state. The first time value is always the duration and the second is the delay. Fill mode decides what happens outside the active period: backwards applies the first keyframe during the delay, forwards keeps the last keyframe after the animation ends, and both does both — essential for entrance animations with a delay, otherwise the element flashes in its final state first.
Timing functions shape the motion. Keywords like ease-out cover most UI cases, cubic-bezier() lets you design custom curves — y values above 1 create an overshoot "pop" — and steps() jumps between discrete frames for sprite sheets and typewriter effects. For smooth performance, animate only transform and opacity, which browsers can run on the compositor without layout or paint.
How to use the CSS Animation Generator
- Pick a keyframe preset such as Fade in, Slide in, Bounce, Pulse, Spin or Wobble. Sensible duration and easing defaults are applied.
- Rename the animation if you like, then set duration and delay.
- Choose a timing function: a keyword, a custom cubic-bezier() curve (with presets) or steps().
- Set iteration count or infinite, direction, fill mode and play state. Press Replay to watch it again.
- Keep the prefers-reduced-motion fallback enabled and copy the CSS: @keyframes, the animation class and the media query.
Example
A staggered entrance that respects reduced-motion preferences:
@keyframes slide-in-bottom {
from {
transform: translateY(100%);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.card {
animation: slide-in-bottom 0.6s ease-out both;
}
.card:nth-child(2) {
animation-delay: 0.1s;
}
@media (prefers-reduced-motion: reduce) {
.card {
animation: none;
}
}Accessibility and performance
- Respect
prefers-reduced-motion. Large movement, spinning, zooming and parallax can trigger nausea or dizziness for people with vestibular disorders. The generated media query switches the animation off; for entrance animations the element simply appears in its final state. - WCAG 2.2.2 requires a way to pause any animation that loops for more than five seconds and is shown alongside other content. Prefer a limited iteration count for decorative loops.
- Avoid flashing more than three times per second.
- Animate
transformandopacityonly. Animatingwidth,top,marginorbox-shadowforces layout or paint on every frame. - Use
will-change: transformsparingly and only on elements that are about to animate — it reserves GPU memory. - Build the moved, rotated or scaled end state with the CSS Transform Generator, and add hover effects to buttons with the CSS Button Generator.
Frequently Asked Questions
What is the difference between CSS animations and transitions?
A transition animates between two states when a property changes, for example on :hover. An animation uses @keyframes, can have many intermediate steps, starts on its own, can loop and can run in alternate directions.
Why does my element jump back after the animation ends?
Without a fill mode the element returns to its normal styles when the animation finishes. Add forwards (or both) to keep the last keyframe applied.
How do I pause a CSS animation?
Set animation-play-state: paused, for example on hover or via a class toggled with JavaScript. Setting it back to running resumes from the same point.
What does cubic-bezier() do?
It defines a custom easing curve with two control points: cubic-bezier(x1, y1, x2, y2). The x values (time) must be between 0 and 1; y values (progress) can go beyond that range to overshoot or anticipate. ease is cubic-bezier(0.25, 0.1, 0.25, 1).
When should I use steps()?
Use steps(n) when the animation should jump between discrete states instead of moving smoothly — sprite-sheet animation, typewriter text, ticking clocks. jump-start, jump-end, jump-none and jump-both control whether the first and last states are held.
Can I animate gradients or text shadows?
Text shadows can be animated in keyframes, though it is more expensive than transform. Gradients themselves cannot be interpolated, but you can animate background-position of a large gradient made with the CSS Gradient Generator, or glowing text from the Text Shadow Generator.