Skip to main content
Beta: Front-End Checklist is currently in beta. Some issues are still being fixed. Thanks for your patience.

Respect reduced motion preferences

Animations respect user motion preferences, avoid seizure-triggering flashing, and include warnings for excessive motion.

Utilities
Quick take
Typical fix time 15 min
  • Use prefers-reduced-motion media query to disable non-essential animations
  • Never flash content more than 3 times per second (seizure risk)
  • Replace motion with opacity/color transitions when reduced motion is enabled
  • Provide user controls to pause or disable animations
Why it matters: Animations can trigger vestibular disorders, migraines, and seizures—respecting motion preferences makes your site usable for millions of affected users.

Rule Details

Some users experience motion sickness, migraines, or seizures from animations. Respect their system preferences.

Code Example

/* Default: animations enabled */
.card {
  transition: transform 0.3s ease;
}
 
.card:hover {
  transform: scale(1.05);
}
 
/* Reduced motion: disable or simplify */
@media (prefers-reduced-motion: reduce) {
  .card {
    transition: none;
  }
 
  .card:hover {
    transform: none;
    /* Use opacity instead of motion */
    opacity: 0.9;
  }
}

Why It Matters

Animations can trigger vestibular disorders, migraines, and seizures—respecting motion preferences makes your site usable for millions of affected users.

Global Animation Disable

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

JavaScript Detection

function prefersReducedMotion(): boolean {
  return window.matchMedia('(prefers-reduced-motion: reduce)').matches
}
 
// React hook
function useReducedMotion(): boolean {
  const [prefersReduced, setPrefersReduced] = useState(false)
 
  useEffect(() => {
    const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)')
    setPrefersReduced(mediaQuery.matches)
 
    const handler = (e: MediaQueryListEvent) => setPrefersReduced(e.matches)
    mediaQuery.addEventListener('change', handler)
    return () => mediaQuery.removeEventListener('change', handler)
  }, [])
 
  return prefersReduced
}
 
// Usage
function AnimatedComponent() {
  const reducedMotion = useReducedMotion()
 
  return (
    <motion.div
      animate={{ x: reducedMotion ? 0 : 100 }}
      transition={{ duration: reducedMotion ? 0 : 0.5 }}
    >
      Content
    </motion.div>
  )
}

Framer Motion Integration

import { motion, useReducedMotion } from 'framer-motion'
 
function Card() {
  const shouldReduceMotion = useReducedMotion()
 
  return (
    <motion.div
      whileHover={shouldReduceMotion ? {} : { scale: 1.05 }}
      transition={shouldReduceMotion ? { duration: 0 } : { duration: 0.3 }}
    >
      Card content
    </motion.div>
  )
}

Safe Animation Patterns

SafeDangerous
Opacity transitionsSpinning/rotating
Color changesParallax scrolling
Border changesZooming in/out
Subtle scale (less than 1.1)Bouncing effects

Exceptions

  • Evaluate the rendered experience before treating a static-code smell as a blocker; interaction timing, browser behavior, and assistive technology output often determine severity.
  • Not every secondary accessibility issue deserves equal weight; prioritize the issue that most directly blocks perception, operation, or understanding.
  • Avoid adding redundant markup or ARIA solely to satisfy a rule when a simpler semantic implementation would eliminate the issue entirely.

Verification

Automated Checks

  • Use browser accessibility tooling, axe, Lighthouse, or equivalent automated checks against a representative rendered state.

Manual Checks

  • Enable "Reduce motion" in system settings
  • macOS: System Preferences → Accessibility → Display
  • Windows: Settings → Ease of Access → Display
  • iOS: Settings → Accessibility → Motion
  • Verify animations are disabled or simplified
  • Check that no flashing content exists

Use with AI

Copy these prompts to use with your AI assistant, or install the MCP server to use directly from Claude, Cursor, or Windsurf.

Check

Verify implementation

Verify that animations respect prefers-reduced-motion, no content flashes more than 3 times per second, parallax and scrolljacking effects have alternatives, and motion warnings appear before pages with excessive animation.

Fix

Auto-fix issues

Use @media (prefers-reduced-motion: reduce) to disable animations. Ensure no flashing exceeds 3 flashes/second. Avoid motion behind static text. Provide motion warnings for immersive experiences.

Explain

Learn more

Explain how motion affects users with vestibular disorders, photosensitive epilepsy, and cognitive disabilities, and why providing motion controls and warnings is essential for inclusive design.

Review

Code review

Review the rendered markup and interactive states that affect Respect reduced motion preferences. Flag exact elements, roles, labels, focus behavior, or keyboard interactions that violate the rule, and note how to verify the fix with browser accessibility tooling or assistive tech.

Sources

References used to support the guidance in this rule.

Further Reading

Tools and supplementary material for exploring the topic in more depth.

axe DevTools
deque.comTool

Rules that often go hand-in-hand with this one.

Prevent seizure-triggering flashing content

Content does not flash more than three times per second to prevent seizures in users with photosensitive epilepsy.

Accessibility
Provide instant anchor scroll option

Smooth scroll animations to anchor links respect motion preferences or provide an instant alternative.

Accessibility
Provide alternatives to parallax effects

Parallax scrolling effects have reduced-motion alternatives or can be disabled by users.

Accessibility
Avoid scrolljacking and custom scroll behavior

Natural scroll behavior is preserved without custom scroll speeds, directions, or hijacked scroll events.

Accessibility

Was this rule helpful?

Your feedback helps improve rule quality. This stays internal for now.

Loading feedback...
0 / 385