Motion & Transition

Easing explorer

Every curve below is a cubic-bezier. Click a thumbnail to inspect it — watch the ball replay the easing, drag the duration, and copy the exact CSS. The two marked (DS) are shipped as tokens; prefer them over ad-hoc curves.

ease-out (DS)
cubic-bezier(0.23, 1, 0.32, 1)
Preview
Duration
transition: transform 1200ms var(--ease-out);

Principles

Animate only transform & opacity

These two are composited on the GPU — they never trigger layout or paint. Animating width, height, top or margin thrashes the main thread and drops frames. Move and fade; don't reflow.

Ease-out for enter, never ease-in

Entering elements should be fast off the mark and settle gently — that's ease-out. Ease-in delays the frames the eye is watching and reads as sluggish at the identical duration.

Easing matters more than duration

A thoughtful curve at 200ms beats a linear tween at any length. Reach for the DS tokens (--ease-out, --ease-in-out) before touching the number.

Exit faster than enter

Dismissal is a decision already made. Play exits at roughly 60% of the enter duration so the UI gets out of the way instead of making the user wait.

Motion must be interruptible

A user can re-open what they just closed. Animations transition from their current state — no waiting for a frame to finish, no janky commit mid-flight.

Animate from the origin

Popovers grow from their trigger; modals scale from center; a swipe follows the finger. Motion that starts where the eye already is feels physical, not decorative.

Purposeful, not decorative

Every animation earns its place: it gives feedback, guides attention, or shows a relationship between states. If it does none of those, cut it.

Respect reduced motion

prefers-reduced-motion means gentler, not off — movement collapses to a fade while functional loops (spinner, skeleton) keep running. Handled globally; components need no extra code.

(hold to see the press feedback)

Durations

The more often a surface is seen, the faster it should animate. Keep UI motion under 300ms — a 200ms dropdown feels more responsive than a 400ms one.

SurfaceDurationNotes
Press feedback100–160 msactive:scale on buttons
Tooltip140 msfires constantly — keep it fast
Panels200 mspopover, menu, select, hover-card
Modals240 msdialog, alert, profile
Exit≈ 60% of enterfaster — the user already decided to dismiss

Reduced motion

Reduced motion means gentler, not off. Under prefers-reduced-motion, panel enter/exit collapse to a plain opacity fade and transform transitions snap to instant — while functional loops (Spinner, Skeleton) keep running. It's handled globally; components need no extra code.

@media (prefers-reduced-motion: reduce) {
  .animate-rise, .animate-modal-in { animation: fade-only 0.12s ease both; }
  *, *::before, *::after { transition-duration: 0.01ms !important; }
}
Configure Theme
Theme
Accent Color
Custom
Gray Family
Appearance
Radius
Scaling
Panel Style
Heading Font
Body Font