Skip to contentWolf-Rayet

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.

ComponentEntersLeavesDuration token
Popup, Dropdown menu, Inline dialogDrops from its trigger by 4px and fades inThe entrance, played backwards--wr-motion-level-2-max-duration
TooltipNudges out of its trigger by 4px and fades inThe entrance, played backwards--wr-tooltip-transition-duration
Modal dialogGrows from 95% and fades inThe entrance, played backwards--wr-modal-transition-duration
BlanketFades inFades out--wr-motion-level-1-max-duration
DrawerSlides in 24px from its edge and fades inThe entrance, played backwards--wr-motion-level-3-max-duration
FlagRises 4px into its stack and fades inRemoved by whatever shows it--wr-motion-level-2-max-duration
SpotlightGrows from 95% and fades inRemoved by whatever shows it--wr-motion-level-3-max-duration
ComponentWhat movesDuration token
ButtonBackground and text colour on hover and press--wr-button-transition-duration
AccordionThe chevron turns when a section opens--wr-accordion-transition-duration
MeterThe fill moves to a new value--wr-meter-transition-duration
Text fieldBorder and background on focus--wr-duration-1
ToggleThe 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.

duration-0 · enter
80ms. Hover on a list item.
duration-1 · enter
110ms. A button press.

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.

Entrance
enter easing, fast start, soft landing
Exit
exit easing, slow start, then gone

Do

Open a surface from where it belongs. A menu opens out of its trigger, and a drawer leaves by the edge it came in from.

Don't

Don't make things appear from somewhere unrelated. The reader loses track of where they came from.

Do

Give components that do the same job the same entrance and exit, so people learn it once.

Don't

Don't give each surface its own style of motion. It makes people relearn every one.

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

Move focus and announce new content to screen readers as the animation starts, so nobody waits behind it.

Don't

Don't wait for motion to finish before moving focus or announcing. It leaves assistive technology behind.

Do

Show errors, confirmations and focus at once.

Don't

Don't hold important feedback behind a slow entrance. People will wonder whether their action worked.

Choosing an easing

TokenUse when
--wr-easing-enterSomething is arriving.
--wr-easing-exitSomething is leaving.
--wr-easing-standardSomething changes in place: a colour, a size, a position on the same surface.
--wr-easing-emphasizedA demand arrives and should be noticed. Rare.
--wr-easing-linearA loop, like a spinner.

Choosing properties

Pick the property that says what happened, and animate one or two at most.

KeyframesWhat changesUsed by
wr-fade-inOpacity from 0Blanket
wr-drop-inOpacity from 0, down from 4px aboveA popup opening below its trigger
wr-rise-inOpacity from 0, up from 4px belowA popup above its trigger, a flag
wr-grow-inOpacity from 0, scale from 95%Modal, spotlight
wr-slide-inOpacity from 0, in from 24px at the start edgeDrawer

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

Pair a fade with a short slide, so the reader sees both that something arrived and where from.

Don't

Don't animate many properties at once. It reads as noise.

Do

Animate transform and opacity. The browser can run them smoothly on slow devices.

Don't

Don't animate width, height or position offsets. They make the browser lay out the page again on every frame.

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.