Reference · UX pattern catalogueAnimation patterns

12 patterns in this category — each with its illustration, what it is, and the fields that matter when you build or review one. Part of the UX pattern catalogue; the raw, agent-readable version is ux-pattern-catalogue/animation-patterns.json.

Foundations

Motion ON Reduced

Reduced Motion animation-001

Gate every animation behind prefers-reduced-motion. The design system zeros all duration tokens automatically; complex animations (parallax, stagger) need explicit @media overrides.

Implementation

Design system tokens (--duration-*) zero out via the prefers-reduced-motion block. For custom animations, wrap in @media (prefers-reduced-motion: no-preference) { }.

Reduced motion

All motion disabled. Essential state transitions use instant crossfade.

transform opacity width height

GPU-Safe Animation animation-002

Only animate transform and opacity — the two GPU-composited properties. Animating width, height, top, left, margin, or padding triggers layout recalculation and causes jank.

Implementation

Use transform: translate(), scale(), rotate() for position/size changes. Use opacity for visibility. Use will-change: transform sparingly on known animated elements.

Reduced motion

N/A — this is a performance rule, not a motion preference.

Entrance exit

opacity 0 → 1

Fade animation-003

The simplest entrance/exit — opacity transition from 0 to 1. Use for content reveals, page transitions, and image loading.

Implementation

opacity: 0 → 1 with --duration-normal + --ease-out (enter) or --ease-in (exit). Combine with translateY for a subtle slide-fade.

Reduced motion

Instant show/hide — no fade animation.

Slide animation-004

Content enters from a screen edge via translateX/Y. Use for panels, drawers, sheets, and mobile navigation.

Implementation

transform: translateX(100%) → translateX(0) with --duration-normal + --ease-out. Vary direction based on context (left for nav, bottom for sheets).

Reduced motion

Instant position change or crossfade — no sliding motion.

Modal scale 0.95→1

Scale animation-005

Element appears by scaling from 0.95 to 1 with an opacity fade. Use for modals, dialogs, popovers, and tooltips.

Implementation

transform: scale(0.95) → scale(1) + opacity: 0 → 1 with --duration-fast + --ease-out. Never scale from 0 — too dramatic.

Reduced motion

Instant appear — opacity only, no scale transform.

Section ▼ Section ▶

Collapse animation-006

Expand or collapse a section without animating height (layout-safe). Use for accordions, collapsible panels, and expandable rows.

Implementation

grid-template-rows: 0fr → 1fr on parent, overflow: hidden on child. Uses --duration-normal + --ease-in-out.

Reduced motion

Instant expand/collapse — no animation.

Micro

Normal Hovered scale(1.02)

Hover Feedback animation-007

Subtle scale or lift on hover for buttons, cards, and interactive elements. Creates a sense of direct manipulation.

Implementation

transform: scale(1.02) or translateY(-1px) + shadow increase on :hover. Use --duration-fast + --ease-spring.

Reduced motion

No transform; color/shadow change only.

Button Pressed scale(0.97)

Press Feedback animation-008

Scale-down effect on :active state for buttons. Provides tactile confirmation of interaction.

Implementation

transform: scale(0.97) on :active. Use --duration-instant + --ease-default.

Reduced motion

No transform; opacity change only.

bad@email Please enter a valid email

Validation Shake animation-009

Horizontal shake animation for form fields with invalid input. Always pair with aria-invalid and visible error text — never shake as the only error indicator.

Implementation

@keyframes shake: translateX(-4px/4px) for 2-3 cycles over --duration-normal. Apply on submit validation failure.

Reduced motion

No shake — rely on red border + error message only.

Loading

shimmer sweep →

Shimmer Loading animation-010

Gradient sweep animation over skeleton placeholders while data loads. Communicates that content is on its way.

Implementation

Animated background-position on a linear-gradient. Container gets aria-busy="true", skeletons get aria-hidden="true".

Reduced motion

Static gray skeleton — no sweep animation.

Scroll

visible entering below fold

Scroll Reveal animation-011

Content fades and slides into view as the user scrolls. Use IntersectionObserver with threshold: 0.1 for efficient detection.

Implementation

IntersectionObserver triggers opacity: 0 → 1 + translateY(20px) → 0 with --duration-normal + --ease-out.

Reduced motion

Content visible immediately — no scroll animation.

0ms 50ms 100ms 150ms

Staggered List animation-012

List items enter sequentially with increasing delays. Creates a cascade effect for card grids, search results, and feeds.

Implementation

Each item gets transition-delay: calc(var(--index) * 50ms). Cap total delay at 500ms (10 items max stagger).

Reduced motion

All items appear simultaneously — no stagger delay.