Applying motion
Which motion each component uses, and how to compose your own when none fits.
Start with the component's own motion
Work out what the element is doing, find the component that does the same thing, and use its motion. Only compose something new when nothing matches.
| Component | Enters | Leaves | Duration token |
|---|---|---|---|
| Popup, Dropdown menu, Inline dialog | Drops from its trigger by 4px and fades in | The entrance, played backwards | --wr-motion-level-2-max-duration |
| Tooltip | Nudges out of its trigger by 4px and fades in | The entrance, played backwards | --wr-tooltip-transition-duration |
| Modal dialog | Grows from 95% and fades in | The entrance, played backwards | --wr-modal-transition-duration |
| Blanket | Fades in | Fades out | --wr-motion-level-1-max-duration |
| Drawer | Slides in 24px from its edge and fades in | The entrance, played backwards | --wr-motion-level-3-max-duration |
| Flag | Rises 4px into its stack and fades in | Removed by whatever shows it | --wr-motion-level-2-max-duration |
| Spotlight | Grows from 95% and fades in | Removed by whatever shows it | --wr-motion-level-3-max-duration |
| Component | What moves | Duration token |
|---|---|---|
| Button | Background and text colour on hover and press | --wr-button-transition-duration |
| Accordion | The chevron turns when a section opens | --wr-accordion-transition-duration |
| Meter | The fill moves to a new value | --wr-meter-transition-duration |
| Text field | Border and background on focus | --wr-duration-1 |
| Toggle | The handle slides across and the track changes colour | --wr-duration-1 |
Interactions
Hover, press and focus. People do these constantly, so the answer has to feel instant.
Use --wr-duration-0 or --wr-duration-1 (80ms or 110ms) with --wr-easing-enter. Change colour, not position. A focus ring appears at once, with no transition at all.
Entrances and exits
An entrance shows where something came from. An exit confirms it is gone. They are not the same motion.
An entrance uses --wr-easing-enter: it starts fast and settles, so the eye can follow it in. An exit is the entrance played backwards, which starts slowly and speeds away, so it never blocks what comes next.
Do
Don't
Do
Don't
Choosing a duration
In Wolf-Rayet duration follows attention, not size.
Use the grant for the level your element declares: 110ms at level 1, 155ms at level 2, 220ms at level 3, 305ms at level 4. A large surface that is only ambient still moves at 110ms. It does not earn a longer entrance by being big.
Do
Don't
Do
Don't
Choosing an easing
| Token | Use when |
|---|---|
| --wr-easing-enter | Something is arriving. |
| --wr-easing-exit | Something is leaving. |
| --wr-easing-standard | Something changes in place: a colour, a size, a position on the same surface. |
| --wr-easing-emphasized | A demand arrives and should be noticed. Rare. |
| --wr-easing-linear | A loop, like a spinner. |
Choosing properties
Pick the property that says what happened, and animate one or two at most.
| Keyframes | What changes | Used by |
|---|---|---|
| wr-fade-in | Opacity from 0 | Blanket |
| wr-drop-in | Opacity from 0, down from 4px above | A popup opening below its trigger |
| wr-rise-in | Opacity from 0, up from 4px below | A popup above its trigger, a flag |
| wr-grow-in | Opacity from 0, scale from 95% | Modal, spotlight |
| wr-slide-in | Opacity from 0, in from 24px at the start edge | Drawer |
Each set has a matching -out set with the same frames. Play it in reverse for the exit. A new name is what makes the browser run the animation again.
Do
Don't
Do
Don't
Checking your work
Turn on reduced motion and go through the whole flow. Every change should still happen, just quicker. Then ask of each animation: if it were gone, would anyone lose track of what happened? If not, remove it.