Quire UI

Motion

Motion that explains, never decorates.

Every component animates through these utilities. None of them use a JavaScript animation library.

UtilityUse for
motion-popPopovers, menus, tooltips, select lists. Scales out of the trigger.
motion-dialogDialogs. A small lift, no zoom.
motion-sheetSheets. Slides in from its edge and follows a swipe.
motion-fadeBackdrops and anything opacity-only.
motion-controlHover and press colour feedback.
motion-swapLabel swaps inside a control, so its width never changes.
motion-messageMessages under a control, like field errors. A short fade and drop.
motion-thumbParts that slide between two places, like a switch thumb.
motion-indicatorA marker that slides to the chosen item, like the tab underline.
motion-panelContent that swaps in place, like tab panels. A fade with a small shift.
motion-toastToasts. Slides in from its edge, follows a swipe and moves the stack between deck and list.

The rules

  1. The more often something is used, the less it animates. Menus and the command palette are near instant. Rare moments can be expressive.
  2. Keyboard input is never animated. Focus the menu button below, open it with Enter and close it with Esc: no transition. Click it instead and you get a short one.
  3. Durations are tokens: 120ms, 160ms, 220ms, with exits at 110ms.
  4. Exits are faster than entrances.
  5. Ease out, never ease in.
  6. Only opacity, scale and translate. No layout properties, ever.
  7. Popups grow from their trigger, starting at 96% rather than zero.
  8. Everything is interruptible. Click a menu trigger rapidly and it reverses smoothly.
  9. Tooltips in a group are instant after the first one.
  10. Reduced motion keeps the fade.

Tokens

--qui-duration-fast: 120ms;
--qui-duration-base: 160ms;
--qui-duration-slow: 220ms;
--qui-duration-exit: 110ms;
--qui-ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
--qui-pop-scale: 0.96;

Change these once and every component follows.

On this page