Skip to main content
Graphite UI

Motion

Motion shows where something came from or where it went. If it teaches nothing, Graphite does not animate it. Ten tokens from the kit’s Motion collection carry every timing, and fifteen components name them in their contracts. Play with the demos: each runs on the real tokens.

Contract 1.0.010 tokensNo bounce

The race

Four dots, one track, one duration. Snap the slider to any of the five duration tokens and press Go.

Duration

duration-slow · 300ms

  1. GraphiteLinear Progress only
  2. NeverIn Never: it starts late and arrives at full speed
  3. GraphiteOut Enter and exit
  4. GraphiteIn-out Already on screen, moving across it

Every dot crosses the same track in the same time. Only the curve differs. In spends its start doing nothing, which reads as lag, then arrives at full speed, which reads as a crash. Graphite never uses it.

Feel it

Four cards arrive, one curve each. Pick the one that feels fastest.

A
B
C
D
Which arrived fastest?

Play them, pick one, then reveal.

The hundredth time

Anything opened by keyboard or used many times a session appears instantly.

Open it, close it, open it again. Then turn the animation off.

Opened 0 times · 0.0 s spent waiting for it

A 300ms open is charming once. A command menu is opened from the keyboard, many times a session, so Graphite opens it at once and the waiting stops climbing.

Where did that come from?

Things enter from their source: a popover from its trigger, a sheet from the bottom edge, a toast from the bottom.

The panel grows from the point it hangs from. Open it a few times.

Catch it

Anything the reader drags can be caught mid-motion. Drag the sheet, fling it, and grab it on its way back.

Drag me down. Fling me. Grab me while I come back.

Tooltip runway

Tooltips wait on first hover, then show instantly while the pointer moves between targets.

Run the pointer along the toolbar. The first label waits half a second; the rest are instant, because you are already reading.

Confirmation

An exit can carry a short confirmation. The picked item flashes, then the menu closes.

Pick an action. The row you chose flashes before the menu closes.

One at a time

One toast at a time, bottom only. The rest wait their turn.

Five toasts, one at a time, at the bottom. Each waits its turn.

    Reduced motion

    Movement becomes a fade or nothing. Feedback stays. Turn the simulation on and go back through the demos.

    Your system setting is no preference. With either, every demo above keeps its feedback and drops its movement: rises become fades, the race dots jump, the tabs indicator jumps, and color changes still ease. Nothing here needed its own code for it. It is one layer in the stylesheet, and a multiplier, --graphite-motion-travel, that every distance is written through.

    Tokens

    The kit's ten, with the components whose contracts name each one. Copy the CSS variable or the Tailwind class.

    Two more live beside them in code only: --graphite-motion-indeterminate, the 1400ms period every loop shares, and --graphite-motion-travel, the multiplier the reduced-motion layer sets to 0. Figma cannot play the sheet spring, so the kit uses duration/slow in its place.

    The rules

    Quoted from the Motion contract (1.0.0). The kit's Read Me carries the same text.

    Rules

    • Motion shows where something came from or where it went. If it teaches nothing, don't animate it.
    • Anything opened by keyboard or used many times a session appears instantly. Menus, command search, tabs, sidebar items, toggles.
    • An exit can carry a short confirmation. The picked item flashes, then the menu closes.
    • Things enter from their source. Popover from its trigger, sheet from the bottom edge, toast from the bottom.
    • Enter and exit use Out. Things moving across the screen use In-out. Linear only for progress. Never ease in.
    • Anything the user drags can be caught mid-motion.
    • Most motion is 120 to 200ms. Nothing runs past 400ms.
    • Tooltips wait on first hover, then show instantly while the pointer moves between targets.
    • Reduced motion. Movement becomes a fade or nothing. Feedback stays.
    • One toast at a time, bottom only. Overlays never stack on overlays.
    • No bounce anywhere. Graphite is a tool.

    Never

    • Never write a raw duration, cubic-bezier() or keyword easing in a stylesheet. naming-check fails on it. A real exception carries motion-allow: <reason> in the comment directly above.
    • Never ease in. An exit is Out at fast, not In.
    • Never overshoot. No back curves, no springs with a damping ratio under 1.
    • Never write a movement distance without --graphite-motion-travel, or reduced motion cannot reach it.
    • Do not add a duration past emphasis. Raise it with the kit, which owns the scale.

    Next steps

    Where the tokens live, and the components that move.

    • Tokens

      Every foundation variable, read live from the page.

    • Menu

      Instant from the keyboard, a flash on the way out.

    • Accessibility

      Contrast and reduced motion, checked as a set.