CSS transitions and keyframe animations move elements over time. Which properties you animate decides whether the browser can stay on the compositor or must re-layout and repaint, and that difference is the source of janky versus smooth motion.
Before you start
You should be comfortable with CSS properties and selectors. This article covers transitions, keyframes and motion performance.
Step-by-step walkthrough
Step 1: Animate transform and opacity
transform and opacity can be handled by the compositor without re-layout, so animating them is cheap. Animating width, height, top or left triggers layout on every frame, which is expensive and causes jank. Prefer transform: translate over animating position.
Step 2: Use transitions for state changes and keyframes for sequences
A transition animates between two states, such as a hover, and is declarative and simple. A @keyframes animation runs a defined sequence, possibly looping, which suits a loading spinner or an entrance. Both can be combined with timing functions.
Step 3: Respect reduced-motion
@media (prefers-reduced-motion: reduce) should reduce or remove non-essential motion, because animation can cause discomfort. Provide a static alternative for large or repeated motion, and keep essential feedback subtle.
Worked scenario
The card lifts on hover using transform, not layout.
.card {
transition: transform 150ms ease, box-shadow 150ms ease;
}
.card:hover {
transform: translateY(-4px);
}
@media (prefers-reduced-motion: reduce) {
.card { transition: none; }
}Walk through the example
The hover translates the card and changes the shadow, both cheap to animate, so the motion stays smooth. The reduced-motion media query removes the transition for users who prefer less motion, while keeping the hover state change. No layout property is animated.
Common mistake
Animating width or position, which forces layout each frame and drops frames. Another is ignoring prefers-reduced-motion, so users who set the preference still get large motion.
Verify the behavior
Use the browser’s performance tools to confirm no layout in the animation frames. Toggle the reduced-motion preference in devtools and confirm the animation is reduced. Compare smoothness of animating transform versus width.
Interview exercise
Why is animating transform smoother than animating left?
Answer and reasoning
transform can be applied on the compositor thread without recalculating layout or repainting, so the browser only composites. Changing left alters layout, forcing the browser to recompute the element’s position and repaint every frame, which is far more expensive and often janks. Same visual effect, very different cost.
Continue learning
Compare motion preferences in Reduced motion and paint cost in Stacking contexts. Read the MDN animation performance guide and try the HTML and CSS interview questions.