
Motion
Ship Framer Motion animations that respect reduced-motion, keyboard users, and screen readers without stripping product polish.
Overview
Motion is an agent skill most often used in Build (also Ship → launch and perf) that teaches accessible Framer Motion patterns—reduced motion, keyboard support, and ARIA—for React UIs.
Install
npx skills add https://github.com/secondsky/claude-skills --skill motionWhat is this skill?
- Four-section accessibility guide: prefers-reduced-motion, keyboard navigation, ARIA integration, and testing workflows
- Recommends wrapping the app in MotionConfig with reducedMotion="user" so OS settings propagate to all Motion children
- Documents how to test Reduce Motion on macOS, Windows, iOS, and Android 9+
- Targets vestibular disorders, attention distraction, epilepsy triggers, and personal preference—not only legal checkbox
- Pairs animation behavior with focus management and assistive-tech semantics
- 4 main guide sections: reduced motion, keyboard, ARIA, testing
Adoption & trust: 586 installs on skills.sh; 165 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You added Motion transitions that look great in dev but ignore OS reduced-motion settings, trap keyboard focus, or confuse screen readers.
Who is it for?
Indie SaaS or marketing sites built with motion/react that need a focused a11y pass without hiring a separate accessibility consultant for every animation.
Skip if: Teams with zero Motion dependency, static HTML/CSS-only sites, or projects where animations are already frozen behind a design-system audit with signed-off tokens.
When should I use this skill?
Adding or reviewing Motion/react animations before shipping UI that moves on screen.
What do I get? / Deliverables
After the skill runs, your Motion tree respects user motion preferences, documents test steps per platform, and aligns animated UI with keyboard and ARIA expectations.
- MotionConfig wrapper pattern
- Accessible animation checklists per platform
- ARIA-aware interaction notes
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Motion UX lives in React/UI implementation, so the canonical shelf is Build → frontend even though accessibility gates also matter at ship time. Covers MotionConfig, component animation patterns, and ARIA hooks in the same layer where JSX and interaction code are written.
Where it fits
Wrap a new dashboard in MotionConfig before shipping sidebar collapse animations.
Verify marketing modals still open with keyboard and honor Reduce Motion on the launch landing page.
Prototype animated onboarding without triggering motion sickness on default OS accessibility settings.
How it compares
Use instead of generic WCAG cheat sheets that never mention MotionConfig or motion-specific reduced-motion APIs.
Common Questions / FAQ
Who is motion for?
Solo and indie frontend developers shipping React apps with the Motion library who own both interaction design and implementation.
When should I use motion?
During Build when adding animated components; during Ship before release when validating launch pages; and when refactoring hero sections or modals that use layout or presence animations.
Is motion safe to install?
It is documentation-style procedural knowledge with no bundled executables; review the Security Audits panel on this Prism page before installing any skill from the registry.
SKILL.md
READMESKILL.md - Motion
# Motion Accessibility Guide Complete guide to making Motion animations accessible for all users, including those with motion sensitivities, keyboard-only navigation, and screen readers. --- ## Table of Contents 1. [Respecting prefers-reduced-motion](#respecting-prefers-reduced-motion) 2. [Keyboard Navigation Support](#keyboard-navigation-support) 3. [ARIA Integration](#aria-integration) 4. [Testing Accessibility](#testing-accessibility) --- ## Respecting prefers-reduced-motion ### What is prefers-reduced-motion? Users can enable "Reduce Motion" in their operating system settings to indicate they prefer minimal animation. This setting helps users with: - Vestibular disorders (motion sickness from animations) - Attention disorders (distraction from movement) - Epilepsy (seizure triggers) - Personal preference ### How to Enable (for testing) **macOS**: 1. System Settings → Accessibility → Display 2. Enable "Reduce motion" **Windows**: 1. Settings → Ease of Access → Display 2. Enable "Show animations" → OFF **iOS**: 1. Settings → Accessibility → Motion 2. Enable "Reduce Motion" **Android 9+**: 1. Settings → Accessibility 2. Enable "Remove animations" ### Implementation with MotionConfig The recommended approach for respecting user preferences: ```tsx import { MotionConfig } from "motion/react" function App() { return ( <MotionConfig reducedMotion="user"> {/* All Motion components respect OS setting */} <YourApp /> </MotionConfig> ) } ``` **How it works:** - `reducedMotion="user"`: Respects OS setting (default behavior) - `reducedMotion="always"`: Force instant transitions (no animations) - `reducedMotion="never"`: Ignore OS setting (always animate) **What happens when enabled:** - All transitions become instant (`duration: 0`) - Spring animations skip to final state - Layout animations still work but happen immediately - Enter/exit animations complete instantly ### Manual Detection (for fine-grained control) When MotionConfig isn't sufficient: ```tsx import { useReducedMotion } from "motion/react" function Component() { const prefersReducedMotion = useReducedMotion() return ( <motion.div animate={{ x: 100 }} transition={{ duration: prefersReducedMotion ? 0 : 0.5, type: prefersReducedMotion ? "tween" : "spring" }} /> ) } ``` **Alternative (vanilla JavaScript):** ```tsx const prefersReducedMotion = window.matchMedia( "(prefers-reduced-motion: reduce)" ).matches <motion.div animate={{ opacity: 1 }} transition={{ duration: prefersReducedMotion ? 0 : 0.3 }} /> ``` ### AnimatePresence and reducedMotion **Fixed**: Motion v12.4.7 (February-March 2025) fixed the issue where AnimatePresence ignored reducedMotion settings. If you're experiencing issues with AnimatePresence not respecting reduced motion preferences, ensure you're using Motion v12.4.7 or later: ```bash # npm npm install motion@^12.4.7 # yarn yarn add motion@^12.4.7 # bun bun add motion@^12.4.7 ``` ### Creating a Reusable Hook ```tsx // hooks/useMotionConfig.ts import { useReducedMotion } from "motion/react" export function useMotionConfig() { const prefersReducedMotion = useReducedMotion() return { transition: { duration: prefersReducedMotion ? 0 : 0.3, type: prefersReducedMotion ? "tween" : "spring", }, initial: (withMotion: Record<string, any>) => prefersReducedMotion ? {} : withMotion, exit: (withMotion: Record<string, any>) => prefersReducedMotion ? {} : withMotion, } } // Usage function Component() { const config = useMotionConfig() return ( <motion.div initial={config.initial({ opacity: 0, y: 20 })} animate={{ opacity: 1, y: 0 }} exit={config.exit({ opacity: 0, y: 20 })} transition={config.transition} /> ) } ``` ### Best Practices **Do:** - ✅ Wrap app in MotionConfig with `reducedMotion="user"` - ✅ Manually check for AnimatePresence components - ✅ Test with reduced motion