What This Template Is For
Animation specs bridge the gap between design intent and engineering implementation. When a designer hands off a prototype with "it should feel smooth," the engineer has no actionable guidance. What easing curve? What duration? What happens on interruption? What about users who prefer reduced motion?
A proper animation spec defines every motion in the interface as a discrete, implementable unit. It captures the trigger event (what starts the animation), the property changes (what moves, fades, scales, or rotates), the timing function (easing curve), the duration, and the fallback for reduced-motion preferences. Without this document, engineers either guess at timing values or skip animations entirely. Neither outcome matches the intended experience.
This template works for any UI that involves motion: page transitions, microinteractions, loading sequences, onboarding tours, and component state changes. It pairs well with the design system documentation template for codifying motion tokens alongside color and typography tokens. Teams running a design review should include the animation spec as part of the review artifact so engineers can flag feasibility concerns before implementation starts.
For teams thinking about motion as a system rather than one-off effects, the design thinking approach helps frame animation decisions around user needs rather than aesthetics alone.
How to Use This Template
- Start with the Motion Principles section. Define the 3-5 guiding principles that every animation in the product should follow. These principles prevent ad-hoc motion decisions and keep the interface consistent.
- Fill in the Global Tokens table with your default durations and easing curves. These become the shared vocabulary between design and engineering. Reference them by name (e.g.,
duration-fast,ease-standard) in individual animation specs. - For each animation, fill in one Animation Unit row. Specify the trigger, properties, timing, and reduced-motion fallback. Group related animations under component headings.
- Include a storyboard or frame sequence for complex multi-step animations. Static mockups cannot communicate choreography. Use numbered frames showing key poses.
- Define the reduced-motion strategy. This is not optional. At minimum, replace motion with instant property changes (opacity crossfade or immediate state swap) when
prefers-reduced-motion: reduceis active. - Share the spec with engineering during sprint planning. Walk through the most complex animations together so engineers can estimate effort accurately.
The Template
Motion Principles
Define 3-5 principles that guide all animation decisions in the product.
| # | Principle | Description | Example |
|---|---|---|---|
| 1 | [Principle name] | [What this principle means in practice] | [Concrete example] |
| 2 | [Principle name] | [What this principle means in practice] | [Concrete example] |
| 3 | [Principle name] | [What this principle means in practice] | [Concrete example] |
| 4 | [Principle name] | [What this principle means in practice] | [Concrete example] |
Global Motion Tokens
| Token Name | Value | Usage |
|---|---|---|
duration-instant | [e.g., 100ms] | Micro-feedback (button press, toggle) |
duration-fast | [e.g., 200ms] | Small element transitions (tooltips, badges) |
duration-standard | [e.g., 300ms] | Standard component transitions (modals, drawers) |
duration-slow | [e.g., 500ms] | Large layout shifts, page transitions |
ease-standard | [e.g., cubic-bezier(0.4, 0, 0.2, 1)] | Most transitions |
ease-enter | [e.g., cubic-bezier(0, 0, 0.2, 1)] | Elements entering the viewport |
ease-exit | [e.g., cubic-bezier(0.4, 0, 1, 1)] | Elements leaving the viewport |
ease-spring | [e.g., spring(1, 80, 10)] | Playful, bouncy interactions |
Animation Units
For each distinct animation, fill in one row.
| ID | Component | Trigger | Properties | Duration | Easing | Delay | Reduced Motion |
|---|---|---|---|---|---|---|---|
| A01 | [Component] | [Event: click, hover, mount, scroll] | [opacity, transform, scale, etc.] | [ms] | [token name] | [ms or none] | [Fallback behavior] |
| A02 | [Component] | [Event] | [Properties] | [ms] | [token name] | [ms or none] | [Fallback behavior] |
| A03 | [Component] | [Event] | [Properties] | [ms] | [token name] | [ms or none] | [Fallback behavior] |
Storyboard (Complex Animations)
For multi-step or choreographed animations, describe the sequence.
Animation name: [Descriptive name]
| Frame | Time | Description | Key Properties |
|---|---|---|---|
| 1 | 0ms | [Starting state] | [Property values] |
| 2 | [ms] | [Intermediate state] | [Property values] |
| 3 | [ms] | [Intermediate state] | [Property values] |
| 4 | [ms] | [Final state] | [Property values] |
Interruption behavior: [What happens if the user triggers a new action mid-animation? e.g., reverse from current position, snap to end state, queue the next animation]
Accessibility: Reduced Motion
| Setting | Behavior |
|---|---|
prefers-reduced-motion: no-preference | All animations play as specified |
prefers-reduced-motion: reduce | [Describe fallback: e.g., replace all transform animations with opacity crossfade at 150ms. Remove parallax, auto-playing loops, and spring effects.] |
Testing checklist:
- ☐ All animations respect
prefers-reduced-motionmedia query - ☐ No animation causes content to be unreachable or unreadable
- ☐ Looping animations have a pause mechanism
- ☐ No animation flashes more than 3 times per second (WCAG 2.3.1)
Performance Budget
| Metric | Target |
|---|---|
| Frame rate during animation | 60fps minimum |
| Main thread blocking | < 16ms per frame |
| Composite-only properties preferred | opacity, transform |
| Layout-triggering properties avoided | width, height, top, left, margin |
Filled Example: Modal Open/Close Transition
Motion Principles
| # | Principle | Description | Example |
|---|---|---|---|
| 1 | Purposeful | Every animation communicates a state change or spatial relationship | Modal slides up from the trigger button, not from the center of nowhere |
| 2 | Quick | Animations should feel responsive, never slow | No transition exceeds 400ms |
| 3 | Consistent | Same type of motion uses same timing across the product | All overlays use ease-enter and ease-exit |
| 4 | Respectful | Honor user motion preferences without degrading functionality | Reduced motion users get instant opacity swap instead of slide |
Global Motion Tokens
| Token Name | Value | Usage |
|---|---|---|
duration-instant | 100ms | Button feedback, toggle switch |
duration-fast | 200ms | Tooltip show/hide, badge count update |
duration-standard | 300ms | Modal, drawer, dropdown |
duration-slow | 500ms | Page transition, onboarding step |
ease-standard | cubic-bezier(0.4, 0, 0.2, 1) | Default for most transitions |
ease-enter | cubic-bezier(0, 0, 0.2, 1) | Elements entering viewport |
ease-exit | cubic-bezier(0.4, 0, 1, 1) | Elements exiting viewport |
Animation Units
| ID | Component | Trigger | Properties | Duration | Easing | Delay | Reduced Motion |
|---|---|---|---|---|---|---|---|
| M01 | Modal backdrop | Modal open | opacity: 0 to 0.5 | 300ms | ease-standard | 0ms | Instant opacity: 0.5 |
| M02 | Modal container | Modal open | opacity: 0 to 1, translateY: 24px to 0 | 300ms | ease-enter | 50ms | Instant opacity: 1, no translate |
| M03 | Modal content | Modal open | opacity: 0 to 1 | 200ms | ease-standard | 150ms | Instant opacity: 1 |
| M04 | Modal container | Modal close | opacity: 1 to 0, translateY: 0 to 16px | 200ms | ease-exit | 0ms | Instant opacity: 0 |
| M05 | Modal backdrop | Modal close | opacity: 0.5 to 0 | 200ms | ease-exit | 50ms | Instant opacity: 0 |
Storyboard: Modal Open Sequence
| Frame | Time | Description | Key Properties |
|---|---|---|---|
| 1 | 0ms | Backdrop begins fade. Modal container is invisible and offset 24px down | backdrop: opacity 0. container: opacity 0, translateY 24px |
| 2 | 50ms | Backdrop at 15% opacity. Modal container begins slide-up and fade-in | backdrop: opacity 0.15. container starts animating |
| 3 | 200ms | Backdrop at full opacity. Modal container nearly in position. Content begins fade-in | backdrop: opacity 0.5. container: opacity 0.85, translateY 3px |
| 4 | 350ms | All elements at final state. Focus moves to first focusable element inside modal | backdrop: opacity 0.5. container: opacity 1, translateY 0. content: opacity 1 |
Interruption behavior: If the user presses Escape during the open animation, reverse all properties from their current interpolated values using ease-exit at 200ms. Do not snap to end state then close.
Accessibility: Reduced Motion
| Setting | Behavior |
|---|---|
prefers-reduced-motion: no-preference | Full slide-up + fade sequence as specified |
prefers-reduced-motion: reduce | Backdrop and modal both crossfade (opacity only) at 150ms. No translateY animation. |
Common Mistakes to Avoid
- Specifying duration without easing. Duration alone does not define how an animation feels. A 300ms linear transition feels mechanical. A 300ms ease-out transition feels natural. Always pair duration with an easing curve.
- Ignoring interruption states. Users click fast. What happens when someone opens a modal, then immediately clicks the close button before the open animation finishes? Define interruption behavior explicitly.
- Forgetting reduced motion. Approximately 30% of iOS users have reduced motion enabled. Skipping this is not an edge case. It is ignoring a third of your mobile audience. See the accessibility glossary entry for baseline standards.
- Animating layout properties. Animating width, height, top, or left forces the browser to recalculate layout every frame, causing jank. Stick to compositor-friendly properties: opacity and transform (translate, scale, rotate).
- Using inconsistent timing across similar components. If modals open at 300ms and drawers open at 500ms, the interface feels inconsistent. Define tokens once and reference them everywhere.
Key Takeaways
- Define motion tokens (durations, easing curves) as a shared vocabulary between design and engineering
- Spec each animation as a discrete unit: trigger, properties, timing, and reduced-motion fallback
- Use storyboards for multi-step animations that static mockups cannot communicate
- Always define interruption behavior for animations that can be cancelled mid-flight
- Test reduced-motion fallbacks as a first-class requirement, not an afterthought
About This Template
Created by: Tim Adair
Last Updated: 3/5/2026
Version: 1.0.0
License: Free for personal and commercial use
