← Back
Best viewed on a desktop. Please switch to a larger device.

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.

cubic-bezier
The only easing
200ms
Micro-interaction
Stagger
Signature pattern
// Staggered title reveal - signature kinetic pattern
MOVE WITH PURPOSE
Loading
// Float + shimmer + expand - three live animations
Easing

Easing Curves - The Foundation

The cubic-bezier curve defines the character of every motion. Linear is mechanical; spring is alive. Hover each to see the ball move.

Linear
cubic-bezier(0, 0, 1, 1)
Constant velocity. Feels robotic and unnatural. Never use for UI - reserved for looping animations like spinners where constant pace is correct.
Ease Out (Enter)
cubic-bezier(0.16, 1, 0.3, 1)
Fast start, slow settle. The correct easing for elements entering the screen - they arrive with energy and come to rest naturally. The most important curve in UI motion.
Ease In (Exit)
cubic-bezier(0.4, 0, 1, 1)
Slow start, fast exit. Correct for elements leaving the screen - they hesitate, then depart decisively. The exit easing complements ease-out on entrance.
Spring (Overshoot)
cubic-bezier(0.34, 1.56, 0.64, 1)
Overshoots then settles - physically plausible, memorable, satisfying. Ideal for button presses, card reveals, scale interactions. The Y > 1.0 value creates the overshoot.
Patterns

Animation Patterns

Six reusable motion patterns - each scroll-triggered so you can watch them perform on page load.

Staggered List Reveal
Each child animates with an increasing delay - creating a cascade that reads naturally top-to-bottom.
nth-child(n) {
animation-delay: calc(n * 0.1s);
animation: stagger-fade 0.5s both;
}
Scale-In Grid
Grid cells scale from 0 with spring easing and staggered delays - feels like a dashboard populating with data.
animation: scale-in 0.4s
cubic-bezier(0.34,1.56,0.64,1)
both;
Dashboard
Analytics
Settings
Reports
Slide-In Sidebar
Navigation items slide from the left with staggered delays - each one arriving after the previous settles.
@keyframes slide-in-l {
from { transform: translateX(-60px);
opacity: 0; }
}
Pulse Ring
Concentric rings scale outward with staggered delays - signals activity, live status, or notification. Three rings at 0.5s offsets.
animation: pulse-scale 1.5s
ease-out infinite;
nth-child(n) { delay: n * 0.5s }
Shimmer / Skeleton
A travelling highlight indicates loading state. Respects the layout - skeleton shows the shape of content before it arrives.
background: linear-gradient(
90deg, surface 25%,
rgba(255,255,255,.1) 50%,
surface 75%) / 400%;
animation: shimmer 1.5s infinite;
SVG Path Draw
stroke-dashoffset animated from the path length to 0 - draws the line as if by hand. Use for chart lines, logo reveals, and hero illustrations.
stroke-dasharray: 300;
stroke-dashoffset: 300;
animation: draw-line 1.5s
ease forwards;
Components

Animated Components

// Animated Buttons

// Animated Inputs

// Progress - Animated on Load

Performance 94%
Load Time 71%
Accessibility 88%
SEO 55%
Navigation

Motion in Navigation

Cards

Card Patterns

ENTER
Pattern · Entrance

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.

translateY(100%) → 0
Pattern · Data

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.

scaleY(0→1) staggered
Pattern · Status

Live Pulse

Concentric rings emanating from a core - the universal "live" signal. Use for real-time data feeds, active users, and system health indicators.

scale 0.5s staggered rings
Timing

Duration Reference

Every animation needs a duration matched to its purpose. Too fast = imperceptible. Too slow = frustrating.

DurationCategoryUse CasesEasingWidth
80–120msMicroButton press feedback, checkbox toggle, hover colourlinear or ease-out
150–250msInteractionDropdown open, tooltip appear, focus ring expandcubic-bezier(0.16,1,0.3,1)
200–350msComponentModal enter, panel slide, card reveal, tab switchcubic-bezier(0.16,1,0.3,1)
400–600msPage / HeroHero title reveal, page transition, dashboard loadcubic-bezier(0.16,1,0.3,1) staggered
600ms–2sAmbientLoading shimmer, floating blobs, rainbow shift loopslinear (looping)
Layout

Full App Layout

◈ Dashboard
▸ Animations
⏱ Timing
∿ Easing
⚙ Settings

Motion Dashboard

482
Animations
200ms
Avg Duration
60fps
Frame Rate
Spring
Top Easing
Animation Triggers · 7 days
Principles

Core Principles

01 · EASING

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.

02 · STAGGER

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.

03 · PURPOSE

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.

04 · PERFORMANCE

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.