Motion & Kinetic
Design that exists in time as well as space. Motion communicates state changes, guides attention, confirms actions, and gives interfaces a quality of weight and physicality. The final dimension of UI design - and the one most often done wrong.
animation-delay: calc(n * 0.1s);
animation: stagger-fade 0.5s both;
}
cubic-bezier(0.34,1.56,0.64,1)
both;
from { transform: translateX(-60px);
opacity: 0; }
}
ease-out infinite;
nth-child(n) { delay: n * 0.5s }
90deg, surface 25%,
rgba(255,255,255,.1) 50%,
surface 75%) / 400%;
animation: shimmer 1.5s infinite;
stroke-dashoffset: 300;
animation: draw-line 1.5s
ease forwards;
// Animated Buttons
// Animated Inputs
// Progress - Animated on Load
Slide Up Reveal
Cards that slide up from below with ease-out easing feel like they're surfacing from underneath the viewport - a natural, physical entrance.
Bar Chart Grow
Chart bars that grow from their base on page entry - anchoring the data in the ground plane and communicating that the numbers are being calculated.
Live Pulse
Concentric rings emanating from a core - the universal "live" signal. Use for real-time data feeds, active users, and system health indicators.
| Duration | Category | Use Cases | Easing | Width |
|---|---|---|---|---|
| 80–120ms | Micro | Button press feedback, checkbox toggle, hover colour | linear or ease-out | |
| 150–250ms | Interaction | Dropdown open, tooltip appear, focus ring expand | cubic-bezier(0.16,1,0.3,1) | |
| 200–350ms | Component | Modal enter, panel slide, card reveal, tab switch | cubic-bezier(0.16,1,0.3,1) | |
| 400–600ms | Page / Hero | Hero title reveal, page transition, dashboard load | cubic-bezier(0.16,1,0.3,1) staggered | |
| 600ms–2s | Ambient | Loading shimmer, floating blobs, rainbow shift loops | linear (looping) |
Motion Dashboard
cubic-bezier Is the Only Easing
The built-in keywords ease, ease-in, ease-out are approximations. Write your own: cubic-bezier(0.16, 1, 0.3, 1) for entrances, cubic-bezier(0.4, 0, 1, 1) for exits, cubic-bezier(0.34, 1.56, 0.64, 1) for spring. The difference is immediately perceptible.
Stagger Reveals All Lists
When multiple elements enter together, add animation-delay: calc(n * 0.08s) to each child. The cascade communicates both the list structure and the sequence of importance. Without stagger, a group of elements entering simultaneously reads as a single flat event.
Every Animation Must Earn Its Place
Decoration in motion is worse than decoration in static design - it repeats on every interaction. Ask: what does this motion communicate that the static state does not? If the answer is "nothing", remove it. Looping ambient animations (shimmer, float) are exempt as they signal state, not transition.
Only Animate transform and opacity
Animating width, height, top, left, background, or font-size triggers layout and paint - causing jank at 60fps. Animate only transform (translate, scale, rotate) and opacity - these run on the GPU compositor thread and never cause layout recalculation.