# Respect reduced motion (Web HIG tip #9)

A slide-in panel looks smooth to most people. For someone with a vestibular disorder, it can bring on dizziness or nausea. Their OS already has a "Reduce motion" setting. Your CSS should listen to it.

**Web HIG tip #9 (Quick #76 / HIG-A11Y-001):** Respect `prefers-reduced-motion` — replace motion with instant state changes or minimal opacity fade.

## Why it matters

Motion that's fine for one person can make another feel sick:

*   People with vestibular disorders, migraines, or motion sensitivity turn on "Reduce motion" so large on-screen movement stops making them unwell
    
*   Parallax, big slide-ins, zooming page transitions, and auto-playing carousels cause the most trouble
    
*   If the page ignores the setting, people have no way to stop it, so they leave
    
*   The fix is small: the browser already exposes the setting as a media query
    

The full HIG (§1.3, Reduced Motion & Animation Safety) makes this a mandatory HIG requirement, even though the matching WCAG criterion (2.3.3 Animation from Interactions) is Level AAA. Auto-playing carousels and looping motion also need a pause control under WCAG 2.2.2 Pause, Stop, Hide (Level A).

## The rule of thumb

Ask: **with "Reduce motion" turned on, does anything still slide, zoom, spin, or scroll by itself?**

If yes, swap that motion for an instant change or a short fade.

```css
/* Don't: the panel always slides in, whatever the user's setting */
.panel {
  transform: translateX(100%);
  transition: transform var(--duration-slow) var(--ease-out-momentum);
}
.panel.is-open {
  transform: none;
}

/* Do: keep the slide by default, and swap it for a short fade when reduced motion is on */
@media (prefers-reduced-motion: reduce) {
  .panel {
    transform: none;
    opacity: 0;
    visibility: hidden; /* a closed panel must not catch clicks or focus */
    transition: opacity var(--duration-base) linear,
                visibility 0s linear var(--duration-base);
  }
  .panel.is-open {
    opacity: 1;
    visibility: visible;
    transition-delay: 0s;
  }
}
```

Motion started from JavaScript needs the same check:

```js
document.querySelector("#to-pricing").addEventListener("click", () => {
  // Check at click time, so a setting changed mid-session is respected
  const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;

  document.querySelector("#pricing").scrollIntoView({
    behavior: reduceMotion ? "instant" : "smooth",
  });
});
```

Use `"instant"`, not `"auto"`: `"auto"` follows your CSS `scroll-behavior`, so a site with `html { scroll-behavior: smooth }` would still glide.

Reduced motion doesn't mean no feedback. A button can still change color and a dialog can still fade in. What goes is the movement: sliding, scaling, bouncing, parallax, and smooth scrolling.

## Do this instead

*   Wrap slide, scale, and parallax effects so they're replaced under `prefers-reduced-motion: reduce`
    
*   Use an instant state change or a minimal opacity fade as the reduced version, so the user still sees that something changed
    
*   Turn off parallax, auto-playing carousels, decorative looping animations, and View Transitions morphing when reduced motion is on. Immersive storytelling surfaces have a narrow exception (§1.5), and they still need a calm equivalent
    
*   Check the same setting in JavaScript before smooth scrolling or starting an animation
    
*   Name the properties you animate instead of using `transition: all` (Quick #85, tip #6), so it's clear what your reduced-motion rules need to cover
    

## Quick check for your app

Turn on reduced motion: in Chrome DevTools, press Cmd/Ctrl+Shift+P, run "Show Rendering", and set "Emulate CSS media feature prefers-reduced-motion" to `reduce`, or use your OS setting. Then open a menu and a dialog, trigger a page transition, and click an in-page link. Nothing should slide, zoom, or smooth-scroll, and every state change should still be visible. A media query existing isn't the same as the motion actually calming down, so test it.

HIG.md §1.3 also includes a global CSS safety net that cuts animation and transition durations and turns off smooth scrolling under reduced motion. Treat it as a backstop, not a replacement for a calm version of each effect.

* * *

The Web HIG is a **behavioral contract** for how the web should behave, not a component library. Design systems define how it looks. The Web HIG defines how it behaves.

*   GitHub: https://github.com/frozonfreak/webhig/discussions/20
    
*   Hashnode: https://thewebhig.hashnode.dev/respect-reduced-motion-web-hig-tip-9
    

*   Dev.to: https://dev.to/frozonfreak/respect-reduced-motion-web-hig-tip-9-1mpn
    
*   Bluesky: https://bsky.app/profile/sastha.bsky.social/post/3mxlbd5iafc27
