Purposeful interface motion
Uses restrained animation to explain state changes and provide feedback while keeping frequent actions quick and accessible.
ui-motion
See how it helpsWhen is it useful?
Use when dialogs, notifications or loading transitions feel abrupt, distracting or inconsistent with the rest of the interface.
What does it help you do?
- Checks the purpose and frequency of each interaction before choosing whether it needs animation.
- Reuses existing motion styles and lightweight tools, with transitions that handle interruption naturally.
- Provides reduced-motion and touch behavior and checks timing in the browser.
Try asking this
Refine our drawer and notification animations. Keep keyboard actions immediate, handle rapidly repeated notifications smoothly and provide a reduced-motion version.
Detailed documentation
Read the skill’s original instructions, examples and checks in their authored language.
Show less
UI Motion
Decide in this order; the first two steps can end with no animation at all, and that is a good result.
1. Should it animate at all?
| How often it happens | Decision |
|---|---|
| 100+ times a day (keyboard shortcuts, command palette) | No animation |
| Tens of times a day (hover, list navigation) | Near-imperceptible or none |
| Occasionally (modal, drawer, toast) | Standard animation |
| Rarely or once (onboarding, success) | Room for delight |
| Keyboard-triggered actions never animate. If it fails this gate, offer an instant state change instead. |
2. Name the purpose
Feedback, where something came from or went, a state change made visible, bridging a change that would otherwise jump, explanation (onboarding and marketing only), or delight (rare moments only). No purpose, no animation; data people read or act on does not move for style.
3. Pick the cheapest tool
CSS transition for hover, press and state toggles; @starting-style for entry without JavaScript; CSS animation for predetermined motion that must stay smooth while the page is busy; element.animate() for programmatic control; a motion library only for springs, layout animation, exit animation and gestures, and only if the project has one. Never add a library for a fade. Extend the project's existing motion tokens instead of creating a second set.
4. Properties
- Animate transform and opacity (clip-path also works). height only for accordions. Never width, margin, padding, top or left.
- Never scale(0): start from scale(0.9–0.97) with opacity 0.
- Popovers, dropdowns and tooltips grow from their trigger (transform-origin at the trigger); modals stay centered.
- translateY(100%) moves an element by its own height; prefer it to fixed pixels.
5. Easing and duration
- Entering or exiting: ease-out. Moving on screen: ease-in-out. Hover and color: ease. Constant motion (progress, marquee): linear. Never ease-in on UI; it delays the moment people watch.
- The built-in keywords are weak; use exact curves:
- ease-out: cubic-bezier(0.23, 1, 0.32, 1)
- ease-in-out: cubic-bezier(0.77, 0, 0.175, 1)
- drawer: cubic-bezier(0.32, 0.72, 0, 1)
- Durations: press feedback 100–160 ms; tooltips and small popovers 125–200 ms; dropdowns and selects 150–250 ms; modals and drawers 200–500 ms. UI motion stays under 300 ms unless there is a reason.
- Springs for drag with momentum, interruptible gestures and things that should feel alive: duration 0.5 with bounce 0.2, or stiffness 100, damping 10, mass 1. Keep bounce at 0.1–0.3, mostly for drag-to-dismiss.
6. Interruption and exit
- Anything triggered rapidly (toasts, toggles) uses transitions, which retarget from the current value, not keyframes, which restart.
- Exit the way it entered: a toast that slides in from the bottom leaves through the bottom.
- Asymmetric timing where people decide: slow on the deliberate part (hold to confirm, 2 s linear), fast on the response (200 ms ease-out).
- Stagger groups by 30–80 ms instead of moving everything at once.
7. Reduced motion and hover, shipped with it
- Under prefers-reduced-motion: reduce, drop movement and position changes and keep gentle opacity or color changes that aid understanding. Fewer and softer, not zero.
- Gate hover motion with @media (hover: hover) and (pointer: fine); touch fires false hovers.
- Nothing flashes more than three times per second; motion that plays on its own for over five seconds needs a pause.
Never ship
- transition: all (name the properties).
- An entrance from scale(0), ease-in on UI, or the built-in ease-out on a deliberate animation.
- Animation on a keyboard shortcut or an action done 100+ times a day.
- UI motion over 300 ms without a reason.
- Keyframes on rapidly triggered elements; layout properties animated.
- Ungated hover motion, or no reduced-motion variant.
Before you finish
- Frequency gate and purpose stated for each animation.
- Tool, properties, curve and duration from the tables above.
- Reduced motion and hover gating checked in the browser.
- Feel checked at 2–5x slow motion or frame by frame where it matters.
Included files 2
LICENSE.txtSKILL.md
