CSS Transition vs Animation Table
| Dimension | Transition | Animation |
|---|---|---|
Trigger | A state change (hover, class toggle) | Starts on its own (or on load) |
Definition | In the destination state's rule | @keyframes + animation-name |
Middle stops | No - interpolates start to end | Yes - arbitrary percentage keyframes |
Looping | No | animation-iteration-count: infinite |
Reverse on undo | Automatic (both directions styled) | Needs a second animation or direction: alternate |
Control from JS | Trigger the state change | play/pause/finish via getAnimations() |
Events | transitionend once per property | animationiteration per loop; animationend at the end |
Best for | Hover states, open/close, focus rings | Loading sequences, attention loops, storytelling |
Transitions and animations are CSS's two motion systems, and they are not interchangeable: a transition REACTS to a state change, an animation PLAYS a performance. The table below compares them across eight dimensions that actually decide which one a feature needs - trigger, definition, looping, and the reverse-on-undo behavior that surprises everyone once.
Bottom line: the decision rule is one sentence. If the word WHEN fits the requirement (when hovered, when opened, when focused), use a transition - style the destination state and let the browser interpolate. If HOW LONG or HOW MANY TIMES fits (a three-stage sequence, an endless pulse), use an animation with @keyframes.
The honest part: the hidden difference is reversal. A transition styled in the hover state reverses itself automatically when the pointer leaves - both directions come free. An animation plays forward and stops; playing it backwards needs animation-direction: alternate or a second keyframes set. Features that must undo gracefully are transitions by default, which is why hover effects and accordions are transition territory even when the animation temptation is strong.
How to use
- Ask the trigger question first: is there a state change to react to (transition), or a sequence to perform (animation)?
- Check the reverse requirement - undo-graceful effects are transitions; one-way performances are animations.
- Use the JS control row when wiring interactivity: getAnimations() pauses and finishes animations; transitions only need the state toggled.
Frequently asked questions
What is the core difference between a transition and an animation?
A transition interpolates between two states when something changes - it needs a trigger (a class, a hover) and defines only the endpoints. An animation runs a @keyframes timeline on its own schedule - it can start on load, hold intermediate stops, and loop without any state change. If removing the trigger would remove the motion, it is a transition; if the motion has a script of its own, it is an animation.
Why does my hover transition not reverse smoothly?
It reverses only if the transition property is declared on the element's BASE state, not only inside the hover rule. A transition defined just in :hover applies while hovered and vanishes on leave - the reversal snaps instantly. The fix is the standard pattern: declare transition on the base selector and only the changed values inside :hover, so both directions interpolate with the same timing.
Can I pause or control a transition from JavaScript?
Not directly - a transition is driven entirely by the state change; your control is toggling the class or value that triggers it. Animations are controllable: element.getAnimations() returns Animation objects with pause(), play(), currentTime scrubbing and a finished promise. If a design needs a real play/pause button, that requirement alone chooses animation over transition.
When do transitions and animations coexist on one element?
Frequently and cleanly: an accordion panel can transition its height on open/close (state-driven) while a spinner inside it animates in a loop (performance-driven). They compose because they occupy different jobs - transitions handle the between-states, animations handle the during-states. The only conflict is both trying to drive the same property at the same time; the animation wins while it runs, which is usually the desired hierarchy.