Skip to the content
BooleanPress UI

Motion

Overlays fade in and out quickly, by one set of timings, and stop moving for readers who ask for less motion.

The policy

Motion tells the reader where something came from; it never makes them wait. So:

  • Entrances: menus, popovers, selects and tooltips appear over 150 ms; dialogs and sheets, which cover more of the page, over 200 ms. They fade and grow slightly, or slide in from the edge they sit on.
  • Exits: every overlay fades out over 100 ms, opacity only, and holds its last frame until it is removed, so it never flashes back for a frame before it goes.
  • Nothing else animates on its own, apart from the spinner and the skeleton's pulse.

The timings are set once, in theme.css, not in each component.

The tokens

Token Value Used for
--bui-duration-fast 100 ms Overlays under reduced motion
--bui-duration-base 150 ms Menus, popovers, selects and tooltips appearing
--bui-duration-slow 200 ms Dialogs, sheets and the phone-width sidebar appearing
--bui-duration-exit 100 ms Every overlay closing
--bui-ease-enter cubic-bezier(0, 0, 0.38, 0.9) Appearing: fast, then settling
--bui-ease-exit cubic-bezier(0.2, 0, 1, 0.9) Closing: quick to leave
--bui-ease-standard cubic-bezier(0.2, 0, 0.38, 0.9) Your own transitions

Override them in brand.css like any other token.

Reduced motion

When the reader's system asks for reduced motion (prefers-reduced-motion: reduce), nothing moves or scales. Overlays keep a 100 ms fade, so they do not appear abruptly; every other animation and transition ends at once, the spinner included.

Stylesheet order

The motion rules live in a CSS layer named overrides. In a WordPress plugin, where Tailwind CSS runs in important mode, declare that layer before Tailwind CSS, so the rules outrank the utilities' own durations:

@layer overrides;
@import "tailwindcss" important;
@import "@booleanpress/ui/theme.css";

In a plain React app the default order needs nothing more. To turn exits off while you compare, set data-bui-exits="off" on <html>: overlays then close at once.