Web Animations That Actually Matter

Learn which CSS animations actually improve UX. Master transitions, timing functions, and staggered animations with an interactive playground.

When (and When Not) to Animate

Animation in UI serves one purpose: helping users understand what happened. A new item slides in so you know where it came from. A deleted item fades out so you know it's gone. A button press gives tactile feedback so you know it registered.

If an animation doesn't serve comprehension or feedback, it's decoration. Decoration slows users down. The loading spinner on a fast app? That's useful feedback. The 800ms page transition? That's decoration — and it makes your app feel slow.

CSS Transitions: The 80/20 of Animation

You can get 80% of the animation value with one CSS property: transition. It smoothly interpolates between states — hover effects, toggled classes, dynamic styles.

The syntax: transition: property duration timing-function delay. For example: transition: opacity 200ms ease-out. That's it. No keyframes, no animation libraries, no JavaScript.

The properties that transition well: opacity, transform (translate, scale, rotate), background-color, box-shadow, and border-radius. Avoid transitioning width, height, top, or left — they cause layout recalculation and stutter on mobile.

*

200-300ms is the sweet spot for most UI transitions. Under 150ms feels instant (might as well skip it). Over 400ms feels sluggish.

Interactive Demo
Preview
Element
Staggered List
CSS Output
.element {
  transition: transform 300ms ease-out;
}

/* Staggered children */
.item:nth-child(n) {
  transition-delay: calc(n * 60ms);
}

Use ease-out for entrances (fast start, gentle stop), ease-in for exits, and 200-300ms for most UI transitions. Stagger lists by 40-80ms per item.

Timing Functions: The Feel of Motion

Linear animation feels robotic. Easing makes motion feel natural. The three you need:

ease-out (fast start, gentle stop) — use for entrances. Elements arrive quickly and settle into place. This is your default for showing new content.

ease-in (gentle start, fast end) — use for exits. Elements accelerate away. Good for removing items or closing modals.

ease-in-out (gentle start, gentle end) — use for state changes where the element stays on screen, like toggling between two positions.

Staggered Animations

When multiple elements appear at once (a list of items, a grid of cards), staggering their entrance by 40-80ms each creates a polished cascade effect. It's simple to implement: just add an increasing delay to each item.

The technique: give each child a transition-delay calculated from its index. Item 0 gets 0ms, item 1 gets 60ms, item 2 gets 120ms, etc. Cap the total stagger time at around 400ms — any longer and it feels slow.

This works beautifully for page load animations, search results appearing, and list items entering the DOM.

Key Takeaways

Only animate to help users understand what happened — not for decoration
CSS transition handles 80% of UI animation needs
200-300ms duration for most transitions
ease-out for entrances, ease-in for exits, ease-in-out for state changes
Only transition opacity, transform, background-color, box-shadow, border-radius
Stagger list items by 40-80ms each, cap total at ~400ms

Related Guides & Tools

Want the full picture?

This free tool checks one slice of UX. Picopi audits your entire page — issues, screenshots, and fixes — web or mobile.