Motion has a job.
Or it has no business shipping.
The interfaces that feel alive aren't the ones with the most animation. They're the ones where every animation is doing one of four jobs — and where the durations are short enough that users notice the result, not the motion.
01 — The four jobs
If it isn't doing one of these, it's decoration.
Every animation in the system should be answering one of these four questions for the user. If a designer can't name which job a transition is doing, the transition probably shouldn't ship — it's motion-for-motion's-sake, which is the fastest way to make a product feel cheap.
Feedback
“Did my click do anything?”
Confirm action: button press, toggle flip, item-added-to-cart. Sub-150ms. The system telling the user “I heard you.”
Continuity
“Where did that come from?”
Connect states: tabs sliding, dialog expanding from its trigger, list item morphing into detail view. 200–400ms. Spatial logic that keeps users oriented.
Hierarchy
“What should I look at?”
Direct attention: error shake, success pulse, notification slide-in. Quick (100–200ms) but visible. Earned attention, not stolen.
Personality
“What kind of product is this?”
Brand signature: hero parallax, page transition style, loading character. Reserved for moments — overuse and the personality becomes an annoyance.
02 — The motion budget
Five tiers. Most things should live in the first three.
The motion budget is the system's discipline against creep. Five named tiers, clear ranges, an opinionated guideline about what belongs where. When a designer proposes a 600ms transition for a button click, the system has an answer: that's a tier-five duration on a tier-two action.
Live demo. All five bars share a synced 4-second cycle. Each fills at the top of its actual ms range — watch how much longer cinematic takes than quick. That delta is what users feel when a tier is misapplied. Most production UI lives in tier 2 and tier 3. Tier 1 is hover/focus (technically not animation in the UX sense), tier 4 is once-a-session (page transitions, modal opens), tier 5 should appear maybe twice in a product. If the distribution looks different, the product is over-animated.
03 — Choreography
When multiple elements move, they need a leader.
A dialog opening isn't one animation. It's a backdrop fading, a panel scaling, content sliding, and focus shifting — four things that need to feel like one. The rule of choreography: one element drives, the rest follow at lower amplitude and slight delay.
Lead
The one element that drives
Usually the most-prominent element of the transition: the modal panel, the page, the selected list item.
duration: 300ms · delay: 0
Support
Same duration, lower amplitude
Backdrop fade, header slide, sidebar shift. Match the lead's duration. Reduce what moves — opacity instead of position, smaller distance, gentler curve.
duration: 300ms · delay: 0
Follow
Delayed, brief, decorative
Content fading in after the panel arrives, a stagger across list items. Starts where the lead ends. Keep individual delays small (40–80ms between items).
duration: 150ms · delay: 200ms+
What you're seeing
- LeadPanel scales + translates up. 400ms ease-out.
- SupportBackdrop opacity fades in alongside. Same 400ms, lower amplitude.
- FollowThree content rows stagger at 100ms / 180ms / 260ms.
Stagger rule. Stagger by 40–80ms per item — long enough to feel sequenced, short enough that the whole list resolves under 500ms. Past 8 items, switch from per-item stagger to a batch fade.
04 — Reduced motion
Some users physically can't use over-animated UI.
Vestibular disorders, migraine, motion sensitivity from concussion or chemotherapy. Browser-level prefers-reduced-motion: reduce is how those users tell the system "please don't move things at me." A design system honors it at the token level so no component has to remember.
Default behavior
Full motion system
- Position transitions (slide, translate)
- Scale transitions (zoom, expand)
- Auto-play (carousels, video, parallax)
- Spring physics, bounce, overshoot
Reduced motion
Crossfades only
- Replace transforms with opacity transitions
- Cap all durations at 100ms
- Pause auto-play; require explicit user trigger
- Remove parallax, sticky-scroll, and easing overshoot
Live demo. Same toast, two motion contracts. The default version slides 40px and fades over 600ms. The reduced version crossfades only, with no translation. Both arrive at the same place; only one moves to get there.If prefers-reduced-motion: reduce is on at the OS level, both panels stay static — this page's reduced-motion media query disables every demo animation.
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}A pragmatic floor. Ship this in the global stylesheet and you've covered 90% of the accessibility need. Components that have meaningful reduced-motion behavior (e.g. a crossfade in place of a slide) can override per-element.
05 — Anti-patterns
The three failures every audited system shows.
Motion regresses faster than any other foundation because animation is the layer designers most enjoy adding. The discipline isn't inventing motion — it's cutting it.
Decorative motion
Avoid
Every card fades + slides + scales on hover
Prefer
Cards subtly tint on hover; only the active card animates
Motion is attention. When everything moves, nothing is highlighted — the user’s eye runs out of where to land. Reserve animation for what’s changing state.
Slow animations on frequent actions
Avoid
Dropdown takes 600ms to open
Prefer
Dropdown opens in 150ms
An animation the user triggers ten times an hour needs to feel instant. Cinematic durations belong on rare moments, not on the path of repeated clicks.
No reduced-motion support
Avoid
Parallax + auto-playing carousels always on
Prefer
@media (prefers-reduced-motion: reduce) replaces animation with cross-fade
Vestibular disorders affect ~35% of adults at some point. Ignoring prefers-reduced-motion isn’t a polish detail — it’s a usability bug that ships a product some people physically can’t use.
06 — Patterns library
Six patterns cover most of what your system ever needs to animate.
A small named vocabulary of motion patterns. When a designer asks "how should this dialog open?" the answer should be one of these by name. New patterns earn a place in the system; they don't get invented per surface.
Slide in
300ms · ease-outElement enters from an edge. The direction implies origin: from the right for notifications, from the bottom for sheets, from the top for command bars.
Use for: toasts · drawers · sheets · command palettes
Crossfade
200ms · ease-in-outOne element fades out as another fades in. The lowest-amplitude transition available — and the one to use when reduced-motion is on.
Use for: tab content · theme switch · empty/filled state
Scale up
400ms · ease-outElement grows from a smaller scale into place. Reads as "something arrived." Pair with opacity to avoid the distracting jolt of pure scaling.
Use for: modals · popovers · tooltips · context menus
Stagger
60ms per itemSequential reveal across a list. 40-80ms between items. Past 8 items, switch to a single batch fade — staggering twenty rows takes too long.
Use for: lists · cards · onboarding steps · form fields
Pulse
one-shot · 600msBrief scale + glow draws the eye to a state change. Fire on event, not on a loop — a perpetually pulsing badge stops being a pulse and starts being noise.
Use for: badge updates · success confirmation · attention nudge
Spin
1.2s · linear · loopThe only motion pattern in the system that's allowed to use linear easing — because it represents truly continuous, mechanical work happening.
Use for: loading spinners · refresh indicators · sync state
The catalog rule
Document every motion pattern with a name, a duration, an easing curve, and three example surfaces. When a new motion is proposed, the question is "which existing pattern is this?" — not "what should we animate?". New patterns earn entry; they don't get invented per feature.
Deep dive
Motion ships on two tokens. Pick them on purpose.
Duration says how long; easing says how. Every animation in the system is a pair of these. The next page is the exact values — five duration tiers, four easing curves, cubic-bezier definitions, and the CSS that ships them.