Foundation

Motion

Motion explains change; it never performs. The entire vocabulary is a fade plus a rise of at most 12px, timed on a five-step scale, and product UI never exceeds 240ms.

Durations

Five steps cover every timing decision. Feedback stays nearly instant, and anything longer than 240ms belongs to marketing surfaces, never the product.

Motion duration tokens
TokenValueUse
duration.xs80msHover and pressed feedback
duration.sm160msExits, overlays, selection controls, small state changes
duration.md240msEntrances, disclosure, page and step changes
duration.lg480msPage-level reveals, marketing only
duration.xl720msRare marketing sequences
Product UI never exceeds md.

480ms and 720ms exist for marketing reveals. Inside the product every interaction animation completes within 240ms; only waiting indicators, skeleton pulses and the feedback run, breathe on lg because they describe time passing.

xs · 80ms
sm · 160ms
md · 240ms
lg · 480ms
xl · 720ms
One fade per step opacity 0 → 1 · ease-out bars drawn at 0.5px per ms

Easing

Two curves do all the work: ease-out settles everything entering, in-out serves movement that returns to rest on screen. Linear exists only for progress indicators.

ease.out

cubic-bezier(0.16, 1, 0.3, 1)

The default curve for everything entering. Every recipe on this page uses it.

ease.in-out

cubic-bezier(0.65, 0, 0.35, 1)

Move and return: an element that travels and settles back within the same view.

ease.linear

linear

Waiting indicators only: spinners, progress bars, and skeleton pulses, the permitted loops.

ease.standard is an alias of ease.out kept for compatibility; new work names ease.out directly.

Recipes

Ten named recipes cover the product. Each demo runs the exact tokens; stages rest in their final state and replay on request.

Motion recipes
RecipeMovementTimingUse
hoverColor and border; press sinks 1pxxs · ease.outHover and pressed feedback on controls
checkGlyph draw-insm · ease.outCheckbox mark drawing in when selected
radioDot fade and settlesm · ease.outRadio dot appearing as the fill settles
switchThumb translatesm · ease.outThumb crossing its 16px track
enterFade + 8px risemd · ease.outCards, panels, and step content entering
exitFade onlysm · ease.outAnything leaving; exits never translate
overlayFade + 4px risesm · ease.outMenus, popovers, and toasts
pageFade + 8px risemd · ease.outRoute-level entrance; enter at page scale
stagger60ms steps6 items maximumList entrances; later items land together
sticky-raiseShadow fadesmNone to raised as content passes beneath

The product implements these with Motion for React; the library contract lives on UI frameworks. The sticky-raise shadow change is drawn on elevation and shadow, and the selection recipes carry the exact values the controls page documents.

hover and press color and border · 80ms ease-out press · sinks 1px every interactive element answers with color or border; nothing lifts or scales beyond the press
check · glyph draws in · 160ms
radio · dot fades and settles · 160ms
switch · thumb crosses 16px · 160ms
check · radio · switch draw-in · dot fade · thumb translate · 160ms ease-out live controls: toggle them; the mark lands and stops, with no bounce
01

Where could a reader first lose the thread of this paragraph?

enter fade + 8px rise · 240ms ease-out

Your draft is saved

exit fade only · 160ms ease-out never translates; the demo resets after the fade
Rerun feedback Start Brainstorming Copy or export draft
overlay fade + 4px rise · 160ms ease-out shadow.overlay
stagger enter per item · 60ms steps 6 items maximum; later items land together

Limits

Fade plus a translate of at most 12px is the entire vocabulary. If an effect needs more than opacity and a short straight move, it does not belong in Inline.

opacity 0 → 1 · rises 8px · 240ms ease-out

A quiet enter. The card fades in, rises 8px from the dashed start, and stops dead at rest; replay it to watch.

scale 0.92 → 1.08 → 1 · overshoots twice · spring

A bouncy entrance. Springs, scale, and overshoot perform for attention; drawn here as a frame, never implemented.

Off the table entirely: scale, bounce, springs, parallax, typewriter reveals, confetti, and perpetual ambient loops. The 12px cap governs elements entering the view; a selection control moves exactly as far as its anatomy defines, so the switch thumb crosses its 16px track on sm and stops without bounce.

Loops are for waiting only.

Spinners and progress bars are the only elements that may repeat, and they run on linear time. Nothing else in Inline moves perpetually; the one looping demo on this page is the waiting bar under rule 6.

Reduced motion

When a person asks for less motion, movement is removed entirely, not shortened. Opacity fades either complete within sm or apply instantly.

Recipe behavior under reduced motion
RecipeDefaultUnder reduced motion
hoverColor and border, 80ms; press sinks 1pxColor and border unchanged; the press translate is removed
check, radio, switchDraw, fade, and slide, 160msThe new state applies instantly; fill and position still carry it
enter and pageFade + 8px rise, 240msFade only within sm, or instant
exitFade, 160msFade within sm, or instant
overlayFade + 4px rise, 160msFade only within sm, or instant
stagger60ms stepsDelays removed; every item lands at once
sticky-raiseShadow fade, 160msFinal shadow appears immediately

Because nothing may encode meaning in motion alone, removing movement costs nothing: every state a transition explains is also carried by color, text, or position in the resting frame. This page obeys the same contract; with reduced motion on, each demo shows its final frame the moment Replay is pressed, and the waiting bar under rule 6 holds still.

Rules

Eight limits keep motion explanatory, and each one runs its own demonstration. When a case is unclear, the quieter option wins.

  1. Start from stillness. Nothing moves until an interaction or a state change gives motion one job to do.
    at rest · no idle motion
    replay is the interaction: one enter, then still again
  2. Fade first, then rise. Opacity carries every transition; translation adds at most 12px, and exits never translate.
    8px rise · in bounds
    32px rise · past the 12px cap

    Your draft is saved

    exit · fade only, never translates
  3. Product UI stops at md. Every product animation completes within 240ms; lg and xl belong to marketing surfaces.
    product marketing only 80 160 240 480 720 the scale to scale: the highlight ends at the 240ms cap
  4. Enter on ease-out, return on in-out. Reserve linear for spinners and progress bars.
    enter · ease-out, lands and stays
    move and return · in-out, 240ms each way
    schematic travel on a track; linear stays reserved for rule 6
  5. Never scale, spring, or bounce. An element stops exactly at its resting point, without overshoot.
    the dashed line is rest
    the card lands exactly on the line and never crosses it
  6. Loop only while waiting. Spinners and progress bars are the only perpetual motion, on linear time.
    waiting · linear · may repeat
    the one legal loop on this page; it stops under reduced motion
  7. Stagger six at most. Steps run 60ms apart and later items land together.
    six steps, 60ms apart; a seventh item would land with the sixth
  8. Remove movement under reduced motion. Fades complete within sm or apply instantly, and no meaning rides on motion alone.
    default · fade + 8px rise
    reduced · fade only, within sm
    with the OS preference on, both settle to the final frame at once