Motion specimen

Seven decisions, and everything that follows from them.

Any one animation is easy. Making a whole product’s worth feel consistent is the hard part, and this page is the system ours come from. Everything below runs on the real spring engine with the real values, so what you see is what the product does.

or click any specimen to replay it
01

Five springs, and only one of them bounces

Four sit at a damping ratio between 0.74 and 0.92 and differ only in speed; bouncy is the one that leaves that line. So the choice is 'how fast', and then separately 'does this one overshoot' — the same two questions the editor's spring pad asks, which is not a coincidence. These are the editor's own preset buttons: there is one vocabulary in this product, not two.

molassesζ 0.92

Deliberate and heavy. Rare enough that using it is a statement.

k 60 · c 18 · m 1.6no overshoot
gentleζ 0.91

Large surfaces that should feel unhurried rather than slow.

k 120 · c 20no overshoot
snappyζ 0.74

The default. Overlays, panels, most entrances.

k 260 · c 243% over
crispζ 0.78

Small controls that should feel mechanical — a switch, an indicator.

k 480 · c 342% over
bouncyζ 0.40

The only one with visible overshoot. Toasts, badges, arrivals.

k 220 · c 1225% over
02

Five durations — and they govern tweens, not springs

This is the decision that surprised me building it. A spring has no duration: it runs until it rests, and how long that takes falls out of stiffness, damping and distance. So this scale governs TWEENS only — opacity, color, anything eased — while a spring's length is derived from the spring. Conflating them has a visible symptom: give a spring a duration shorter than its settle time and the exporter can no longer emit a native spring, so you get a hundred sampled numbers instead of one line.

instant90ms
fast140ms
base220ms
slow320ms
slower480ms
03

Five distances. Never an arbitrary 23

Two entrances that travel 16px and 23px look like two people worked on them. The top of the scale is deliberately modest — nothing in an interface needs to travel 120px to say it arrived; that reads as a page transition, which is a different statement.

hair4px
short8px
base16px
long28px
far48px
04

Opacity leads transform

A thing is fully visible before it has finished arriving, so you read it while it settles rather than watching a ghost slide into place. Left: the fade finishes at 220ms while the spring runs on. Right: both locked to the same length, which is what it looks like when nobody decided.

Opacity leads — the rule
Locked together — the mistake
05

An exit is the entrance, faster and shorter

Leaving is not a performance — the user has already decided. Reversing an entrance at the same speed makes dismissing something feel like it is arguing with you. So an exit takes the next stiffer spring and travels 60% of the distance.

Enter · snappy · 28px
Exit · crisp · 17px
06

Stagger is 60, 100 or 160ms — and the step must be even

Not a style rule, an export rule. An even step is what collapses into staggerChildren: one number that any number of children inherit. An uneven step exports as N separate animations, which is longer and worse code. These are the same three values the editor's multi-select control offers.

tight60ms
base100ms
loose160ms
07

Emphasis returns, so its return is a tween

A nudge in scale that comes back. The push out uses the spring; the return does not — a spring returning to where it started overshoots past it and reads as a wobble rather than as attention. One rule, and it is the sort of thing only becomes obvious next to the version that gets it wrong.

Spring out, tween back — the rule
Spring both ways — the wobble

Everything on this page is generated from the same values the product uses. Change one and this page changes with it, and so do the twelve animated components at /components, which are built on them.