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.

/* 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:

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.