# Reduced motion preference is respected

- **Pattern:** `ab-000069` (`accessibility-basics.visual-color.reduced-motion-respected`)
- **Severity:** info
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000069
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000069)

## Why it matters

For users with vestibular disorders, conditions like PPPD (Persistent Postural-Perceptual Dizziness) or Meniere's disease, parallax scrolling, auto-playing carousels, and animated page transitions can trigger nausea, vertigo, and seizure-like symptoms. These users configure their OS to prefer reduced motion as a medical accommodation. WCAG 2.2 SC 2.3.3 (Animation from Interactions) — a AAA criterion — requires that motion animation triggered by interaction can be disabled. Section 508 2018 Refresh 302.1 covers a general right to usability. Even at AA, animations that play unconditionally violate reasonable usability expectations for a significant user population. The `prefers-reduced-motion` media query is supported in all major browsers and is a one-to-one signal from user OS settings.

## Severity rationale

Info because failing to respect reduced-motion preferences is a AAA-level concern that affects a smaller population, but it can trigger genuine medical symptoms in vestibular disorder patients.

## Remediation

Add a global `prefers-reduced-motion` override to your CSS that kills durations rather than animations entirely — this preserves state changes while removing kinetic movement.

```css
/* globals.css */
@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;
  }
}
```

For JavaScript animations (Framer Motion, GSAP, CSS-in-JS), check the preference at runtime:

```tsx
const prefersReducedMotion = window.matchMedia(
  '(prefers-reduced-motion: reduce)'
).matches;

// In Framer Motion
<motion.div
  animate={{ x: 100 }}
  transition={{
    duration: prefersReducedMotion ? 0 : 0.3,
  }}
/>

// Or use the built-in hook
import { useReducedMotion } from 'framer-motion';
const shouldReduce = useReducedMotion();
```

Autoplay carousels and video backgrounds should pause entirely — not slow down — when reduced motion is preferred. The `scroll-behavior: auto` override prevents smooth scroll from triggering vestibular reactions.

## Detection

- **ID:** `reduced-motion-respected`
- **Severity:** `info`
- **What to look for:** Enumerate every relevant item. Check whether the application respects the `prefers-reduced-motion` media query. Look for CSS animations and transitions. Verify that animations are disabled or significantly reduced when the user has set their OS to prefer reduced motion (Windows > Ease of Access > Display, macOS > Accessibility > Display).
- **Pass criteria:** At least 1 of the following conditions is met. CSS animations and JavaScript animations check `prefers-reduced-motion` media query. Animations are disabled or significantly reduced when the preference is set.
- **Fail criteria:** Animations play regardless of `prefers-reduced-motion` preference, or the check is not implemented.
- **Skip (N/A) when:** The application has no CSS or JavaScript animations.
- **Detail on fail:** Describe animation issues. Example: `"Page has multiple CSS animations and transitions. No prefers-reduced-motion checks. Carousel autoplays even when user has reduced motion enabled."`
- **Remediation:** Respect motion preferences in CSS and JavaScript:

  ```css
  /* With motion preference respected */
  @media (prefers-reduced-motion: reduce) {
    * {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
  }

  /* Or disable animations selectively */
  .carousel {
    animation: slide 3s ease infinite;
  }

  @media (prefers-reduced-motion: reduce) {
    .carousel {
      animation: none;
    }
  }
  ```

  In JavaScript:

  ```ts
  const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  if (!prefersReducedMotion) {
    // Play animation
  }
  ```

---

## External references

- wcag 2.3.3
- section-508 302.1

Taxons: accessibility

HTML version: https://auditbuffet.com/patterns/ab-000069
