Ch. 5 · HTML & CSS

CSS Transforms and Animations

Animate transform and opacity for smooth motion, use transitions and keyframes, and respect reduced-motion preferences.

~2 min readintermediateupdated Oct 5, 2026

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; }
}
CSS

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.

More in HTML & CSS

read ✓HTML & CSS · easy

CSS aspect-ratio and Layout Stability

Reserve space for media with aspect-ratio, combine it with object-fit, and avoid the layout shift the old padding hack caused.

~2 min readread →
read ✓HTML & CSS · hard

The CSS :has() Selector

Style a parent based on its children with :has(), handle form states, and use it without hurting performance.

~2 min readread →
read ✓HTML & CSS · hard

CSS Cascade Layers

Control the cascade order with @layer, keep specificity low, and understand how unlayered styles fit in.

~2 min readread →
esc