Get started
Fabricator UI

Search documentation

Search pages, components, blocks, styles and colours.

Motion

PreviousNext

Three spring speeds, 90, 210 and 290ms, with quicker exits and one scale for all of them.

Installation

The easings and duration tokens ship with the foundations, which every Fabricator component installs:

bunx --bun fabricator-ui@latest add foundations

Three speeds

Every transition picks one of three tiers. Small changes use fast, things that slide use moderate, and dialogs use slow. No component invents its own timing, so components that were never designed together still move at the same pace.

Each ball enters on its tier's spring and returns on the exit tween, about a quarter quicker. Change Motion in the settings menu to scale all three.
TierEnterExitUse
fastduration-fast ease-spring (90ms)duration-fast-exit (70ms)Hover, focus, colour, fades, tooltips, checkboxes and radios, popups, accordion, Fluid Hover
moderateduration-moderate ease-spring (210ms)duration-moderate-exit (160ms)Selection backgrounds, tab indicators, switch thumbs, sheets and drawers, the sidebar
slowduration-slow ease-spring-bounce (290ms)duration-slow-exit (220ms)Dialogs

Use the tier names, not milliseconds: duration-fast, duration-moderate and duration-slow for entrances, duration-<tier>-exit for exits, and delay-<tier> to wait one tier. Each one reads a token, so the speed setting changes them all.

Slow in, faster out

An exit on the same spring as the entrance lingers: by the time it settles you have already moved on. Exits use a plain tween, about a quarter quicker than the entrance: 70, 160 and 220ms.

Invite peopleOpens on the slow spring.
Exit on the same springDrags on the way out
Invite peopleOpens on the slow spring.
Exit one tier quickerGone before you look for it
Both panels open on the slow spring. Close the left one, then the right one: the left lingers on the way out.

Easings

Springs are written as CSS linear() easings, sampled from a spring that settles exactly at the end of its duration. They are theme tokens, so they work with any Tailwind transition or animation utility.

UtilityCurve
ease-springA critically damped spring: lands with no overshoot.
ease-spring-bounceA spring with a small bounce (0.12), for dialogs.
ease-exitcubic-bezier(0.25, 0.1, 0.25, 1), for exits.
<div className="transition-transform duration-moderate ease-spring" />

Rules

  • Animate transform and opacity. Avoid animating layout.
  • Popups enter with a fade, a 0.97 zoom and a 4px slide from the trigger side, on the fast tier.
  • Dialogs enter with a fade and a 0.97 zoom on the slow tier.
  • Pressing a button changes its background, never its scale.

Speed

Every duration is a token. The foundations define the base values and one multiplier:

TokenValue
--motion-fast90ms
--motion-fast-exit70ms
--motion-moderate210ms
--motion-moderate-exit160ms
--motion-slow290ms
--motion-slow-exit220ms
--motion-scale1

The duration-* and delay-* utilities multiply the tier by --motion-scale where they are used, so you can slow an app down, speed it up, or stop it, for the whole page or one part of it:

:root {
  --motion-scale: 0.7; /* snappier */
}
 
.onboarding {
  --motion-scale: 1.4; /* more relaxed, only here */
}

0 turns animation off: every transition and enter/exit animation finishes instantly. This site's settings menu has the same control (Relaxed, Default, Snappy, Off).

Reduced motion

Reduced motion means fewer and gentler animations, not none. With prefers-reduced-motion: reduce, components keep their fades and drop their slides and zooms, and Fluid Hover jumps instead of gliding. The foundations do this globally, so components don't need their own motion-reduce: variants. It applies whatever --motion-scale is set to.