CSS Animations Table
| Piece | What it does | Field note |
|---|---|---|
@keyframes name | Defines the animation stages | 0%/from and 100%/to are the endpoints; middle stops optional |
animation-name | Attaches a keyframe set | Multiple names comma-separate into one timeline |
animation-duration | One cycle length | 0s is legal and instant - a common silent bug is forgetting the unit |
animation-timing-function | Pacing inside the cycle | ease default; linear for loops; cubic-bezier for custom |
animation-delay | Wait before starting | Negative values start mid-animation - handy for offset loops |
animation-iteration-count | Repeats | number or infinite |
animation-direction | alternate, reverse | alternate is the ping-pong look without keyframe duplication |
animation-fill-mode | Styles before/after play | forwards keeps the final frame - without it the element snaps back |
animation-play-state | paused / running | The pause button; toggle via class, not JS style writes |
animation shorthand | All eight in one line | First time value = duration, second = delay - order matters |
will-change | Performance hint | Promote only what animates; every hint costs memory |
prefers-reduced-motion | Media query gate | Wrap decorative animation in it - motion can literally sicken users |
CSS animations run on their own schedule - no state change required, no JavaScript involved. You define stages in @keyframes, attach them with the animation property, and the compositor handles the rest. The table below is the working twelve: every property in the family, what it actually controls, and the field note for the behavior that surprises people.
Bottom line: transitions (the sibling feature) react to a change; animations perform. That difference decides when to use which - hover states and toggles want transitions, loading sequences, attention pulses and looping scenes want animations. And the most-copied snippet on this page exists because of one bug everyone hits: without animation-fill-mode: forwards, the element snaps back to its original style the instant the animation ends.
The honest part: the shorthand's argument order is load-bearing. The first time value is the duration, the second is the delay - swap them accidentally and your animation waits instead of running. And the accessibility rule is not decoration: motion sickness is a documented vestibular response, so decorative animation belongs behind the prefers-reduced-motion media query, where the animation simply never starts for users who opt out.
How to use
- Define the stages in @keyframes first - 0%/from to 100%/to, with any percentage stops between.
- Attach with the shorthand and read the argument order carefully: duration, then delay, then the rest by name.
- Finish with the two production attributes: fill-mode: forwards when the final state should stick, and the reduced-motion gate for anything decorative.
Frequently asked questions
What is the difference between CSS animations and transitions?
Transitions need a state change - a class toggle, a hover - and interpolate between the two states once. Animations play according to their own timeline: they can start on page load, loop, alternate direction, and hold intermediate stops at arbitrary percentages. Rule of thumb: if the word 'when' applies (when hovered, when opened), it is a transition; if the word 'how long' or 'how many times' applies, it is an animation.
Why does my element snap back after the animation ends?
Because animations do not change the underlying style - they apply values only while running. When the animation completes, the element returns to whatever the stylesheet says, unless animation-fill-mode: forwards tells it to keep the final keyframe's values. The same property's backwards value applies the first keyframe during a delay, and both covers the whole timeline. This single attribute is the difference between a fade-in that stays and one that flashes.
How does the animation shorthand know duration from delay?
By order: when two time values appear, the first is duration and the second is delay. animation: slide 2s 1s infinite means two seconds long starting after one second. With only one time value, it is always the duration. Because the rest of the values are keywords that can appear in any order, the safe habit is shorthand for the times, longhand for everything you actually care about reading later.
How do I pause a CSS animation from JavaScript?
Toggle animation-play-state between paused and running - ideally by adding or removing a class, not by writing inline styles. element.getAnimations() is the modern read side: it returns the Animation objects behind every running animation, with currentTime for scrubbing and finished as a promise for 'do something when it ends'. The old loop-and-check trick is retired; the Web Animations API speaks CSS animation natively now.