CSS Animations Table

PieceWhat it doesField note
@keyframes nameDefines the animation stages0%/from and 100%/to are the endpoints; middle stops optional
animation-nameAttaches a keyframe setMultiple names comma-separate into one timeline
animation-durationOne cycle length0s is legal and instant - a common silent bug is forgetting the unit
animation-timing-functionPacing inside the cycleease default; linear for loops; cubic-bezier for custom
animation-delayWait before startingNegative values start mid-animation - handy for offset loops
animation-iteration-countRepeatsnumber or infinite
animation-directionalternate, reversealternate is the ping-pong look without keyframe duplication
animation-fill-modeStyles before/after playforwards keeps the final frame - without it the element snaps back
animation-play-statepaused / runningThe pause button; toggle via class, not JS style writes
animation shorthandAll eight in one lineFirst time value = duration, second = delay - order matters
will-changePerformance hintPromote only what animates; every hint costs memory
prefers-reduced-motionMedia query gateWrap decorative animation in it - motion can literally sicken users
Reference: the MDN CSS animations guide. The split from transitions (the sibling table on this site): transitions react to a state change, animations play on their own schedule - keyframes let you control middle stops, looping and direction that transitions cannot express. Bottom line: two attributes cause most animation bugs - missing animation-fill-mode: forwards (the element snaps back when the animation ends) and a forgotten duration unit. Accessibility first: gate decorative motion behind prefers-reduced-motion. Related tools: CSS transitions table for the state-change sibling, pseudo-elements table for animating ::before/::after, and web vitals table - animations belong on the compositor, not layout.

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

  1. Define the stages in @keyframes first - 0%/from to 100%/to, with any percentage stops between.
  2. Attach with the shorthand and read the argument order carefully: duration, then delay, then the rest by name.
  3. 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.

Related tools