Skip to content

Motion

Motion in Umia should help people follow what changed, and never slow them down. Most of the time that means short, quiet transitions. Often it means no animation at all.

--motion-easing-entranceAppearing
--motion-easing-standardMoving on screen
--motion-easing-exitLeaving
Speed

Start with how often someone sees it.

  • Things people use many times a day don’t animate. That includes sidebar links, keyboard shortcuts and moving through a list. A highlight should jump straight to the new item.
  • Hover and press feedback stays small and fast.
  • Menus, dropdowns, dialogs and toasts get a short entrance, so the change is easy to follow.
  • Rare moments, like a first success, can have a little more character.

Every animation needs a reason you can say in one sentence, such as “it shows where the menu came from” or “it confirms the copy worked”. “It looks nice” isn’t enough for something people see often.

Use the motion tokens instead of raw numbers.

  • --motion-duration-fast (100ms) is for hover, press and other instant feedback.
  • --motion-duration-normal (200ms) is the default for dropdowns, tooltips, switches and small changes.
  • --motion-duration-slow (300ms) is for dialogs, drawers and larger surfaces coming in.
  • --motion-duration-instant (0ms) is for turning motion off.

Keep interface motion at 300ms or less. Make exits quicker than entrances, because the person has already moved on.

  • --motion-easing-entrance is for things that appear. It starts fast and settles gently, so it feels responsive.
  • --motion-easing-standard is for things that move or change while they’re on screen, like a sliding selection.
  • --motion-easing-exit is for things that leave.

Only use linear for constant motion, like a spinner. Don’t use ease-in for something appearing, because it holds back the part people are watching.

  • Buttons shrink to 97% while pressed. Larger surfaces, like cards, shrink to 99%.
  • Things that appear start at 95–97% of their size and transparent, never from nothing.
  • Menus and popovers grow from the control that opened them. Dialogs are the exception and grow from the centre.
  • When something is copied, the icon turns into a check with a short pop.
  • A segmented control’s highlight slides to the option you pick.
  • Pages switch instantly, with no transition.
.menu {
transform-origin: top left;
transition:
opacity var(--motion-duration-normal) var(--motion-easing-entrance),
transform var(--motion-duration-normal) var(--motion-easing-entrance);
}
@starting-style {
.menu[open] {
opacity: 0;
transform: scale(0.97);
}
}

In Tailwind, pass the tokens as arbitrary values:

<button class="transition-[scale] duration-[var(--motion-duration-fast)] ease-[var(--motion-easing-standard)] active:scale-[0.97]">

Animate transform and opacity wherever you can. Changing width, height, margins or position makes the browser lay out the page again on every frame, which can stutter on slower devices.

Some people turn on reduced motion in their system settings because movement makes them feel unwell. Respect it.

  • Remove movement, like sliding, scaling and spinning decoration.
  • Keep fades and colour changes, so changes in state are still clear.
@media (prefers-reduced-motion: no-preference) {
.card:active {
transform: scale(0.99);
}
}

In Tailwind, add movement with motion-safe: and switch it off with motion-reduce:.