CSS transition vs animation: which do I need?
Use a transition when a property changes because of a state like :hover or a class toggle. Use an animation when the motion should run by itself, repeat, or pass through intermediate steps.
#Transition
.button {
background: var(--brand-500);
transition: background 0.2s ease, transform 0.2s ease;
}
.button:hover {
background: var(--brand-600);
transform: translateY(-2px);
}Two states, and the browser interpolates between them.
#Animation
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.4; }
}
.loading { animation: pulse 1.5s ease-in-out infinite; }No state change required, and it can repeat or pass through midpoints.
#Never transition "all"
transition: all 0.3s; /* avoid */It also animates layout properties, forcing the browser to recompute geometry every frame — and it will animate properties you did not intend, including ones added later. Name what you change.
#Only two properties are cheap
transform and opacity are handled by the compositor and do not trigger layout or paint. Everything else — width, height, top, margin, box-shadow — costs work on every frame.
Animate position with transform: translate(), not top/left. Animate size with transform: scale() where you can.
#Honour reduced motion
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}Some people get genuinely motion sick from large transitions and parallax. Five lines, not optional.
#Timing that feels right
Most UI transitions want 150–250ms. Under 100ms reads as instant; over 400ms feels sluggish. ease-out suits things entering, ease-in suits things leaving.