Tags: ux web-dev concept

Reduced Motion

Date: 2026-08-17


A system-level preference for less animation, set by people for whom motion causes genuine physical symptoms. It’s one CSS media query, it’s widely supported, and ignoring it means shipping something that makes a subset of your customers feel ill.


prefers-reduced-motion is an operating-system setting exposed to CSS and JavaScript, indicating the user has requested minimal non-essential motion.

Why people set it

Vestibular disorders — inner-ear conditions affecting balance — make certain motion genuinely nauseating. The symptoms are dizziness, nausea, headache and disorientation, and they’re triggered by the same effects designers reach for:

Most triggering:

  • Parallax scrolling
  • Large-scale movement across the viewport
  • Zoom and scale transitions
  • Spinning or rotating elements
  • Auto-playing video and carousels
  • Scroll-jacked animation

Less triggering:

  • Small fades
  • Colour changes
  • Short, small movements

Others set it for motion sensitivity, migraine, attention reasons, or simple preference — and none of those require justification.

The implementation

@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;
  }
}

Near-zero rather than zero — some scripts depend on transition or animation events firing, and setting the duration to 0 can prevent them, breaking behaviour rather than just removing motion.

In JavaScript:

const reduce = window.matchMedia(
  '(prefers-reduced-motion: reduce)'
).matches
 
if (!reduce) startCarouselAutoplay()

JavaScript-driven animation is not covered by the CSS query — canvas, WebGL, scroll-triggered libraries and autoplay all need the check explicitly.

Reduce, don’t remove

The distinction that matters:

WRONG    remove all motion
         → state changes become
           instantaneous with no
           indication anything happened
         → the causality cue is lost for
           people who may need it most

RIGHT    replace movement with an
         instant but still-visible
         change
         → a modal appears rather than
           sliding, and it still clearly
           appeared
         → a fade of 0.01s is
           imperceptible and still fires
           the events

Motion communicates. The goal is removing the distress, not the information — Motion and Transitions.

The build-it-in approach

Rather than a global override bolted on at the end:

:root {
  --duration-base: 250ms;
}
 
@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-base: 0.01ms;
  }
}
 
.modal {
  transition: opacity var(--duration-base);
}

One token, changed once. Every component using it respects the preference automatically, and nothing has to be remembered per component — Design Tokens, Easing and Duration.

What else it should affect

Beyond CSS transitions, and these are routinely missed:

AUTO-PLAYING CAROUSELS   stop autoplay
AUTO-PLAYING VIDEO       don't
PARALLAX                 disable entirely
ANIMATED GIFs            offer a pause,
                         or a static poster
SMOOTH SCROLL            scroll-behavior:
                         auto
LOADING SHIMMER          static skeleton
                         — Loading and Perceived Performance
CONFETTI / CELEBRATION   skip it

See: Loading and Perceived Performance

Auto-playing carousels are the worst offender in retail — large-scale movement, unrequested, repeating, and typically ignored past the first slide anyway.

Separate from the preference, WCAG requires that motion lasting more than five seconds, or auto-updating content, must have a mechanism to pause, stop or hide it — which applies whether or not the preference is set — WCAG.

Testing it

macOS      System Settings → Accessibility
           → Display → Reduce motion
Windows    Settings → Accessibility →
           Visual effects → Animation
           effects
iOS/Android  Accessibility → Motion
DevTools   emulate the media feature
           directly

Toggle it and walk a purchase. The bugs it surfaces are usually the JavaScript-driven animations nobody wired to the check.