Accessibility & Standards

Reduced Motion

Definition

Large or unexpected movement on screen makes some people ill. Vestibular disorders, migraine and motion sensitivity turn a parallax hero, a sliding page transition or an auto-rotating carousel into nausea, dizziness or a headache that outlasts the visit by hours. Every major operating system now offers a switch for this — Reduce Motion on macOS and iOS, Animation effects on Windows, Remove animations on Android — and browsers expose the setting to CSS through the prefers-reduced-motion media query, defined in Media Queries Level 5. The query has two values, no-preference and reduce, and a page that never checks it simply animates regardless. WCAG touches the same ground from several directions: 2.3.3 Animation from Interactions at level AAA, 2.2.2 Pause, Stop, Hide at level A for anything that moves automatically for more than five seconds, and 2.3.1 Three Flashes or Below Threshold at level A for flashing content.

Why It Matters

This is one of the cheapest accessibility wins there is. A single media query block, three or four lines long, can neutralise every transition on a site, and unlike alt text or a tag tree it needs no per-element judgement. The cost of skipping it is real and immediate: a reader who opens a page with a full-screen parallax scroll and has to close the tab and lie down is not coming back, and no error appears in any log to tell you it happened. Motion is also a battery and performance cost, so the reduced path tends to be the faster one. Roughly speaking, the preference is not rare — it is on by default for anyone who has ever turned it on to stop their phone making them queasy, and it stays on everywhere.

How It Works

Write your animations as normal, then add a block guarded by the media query at reduce and override what moves. The blunt version sets animation-duration and transition-duration to 0.01ms with an important flag across all elements, plus animation-iteration-count of 1 — near-zero rather than zero, because some scripts wait for an animationend event that never fires if the duration is a flat zero. The considered version keeps opacity fades, which almost nobody objects to, and removes only the translation, scale, rotation and parallax. JavaScript can read the same signal with matchMedia on the string prefers-reduced-motion: reduce, which matters for anything animated outside CSS, and the media query object fires a change event if the setting is flipped mid-session. An animated GIF is the awkward case, because it carries its own timeline and ignores the preference entirely — swap it for a video element with controls and no autoplay, or serve a still frame, if the motion is anything more than a small looping detail.

Real-World Example

A designer publishes a portfolio as a static site at folio.99helpers.site, with each project card sliding 80 pixels and scaling as it scrolls into view. Adding one media query that cuts every transition to near zero left the layout identical and the motion gone for anyone with the setting on. Nothing else changed: same files, same CSS bundle, about 300 extra bytes before compression. 99helpers serves the CSS exactly as written, so the behaviour is decided entirely in the file you upload.

Common Mistakes

  • Treating the preference as a niche request and skipping it — the switch is a system setting people turn on once, so the page is tested against it far more often than the analytics suggest
  • Setting durations to a flat zero — scripts that wait for a transitionend or animationend callback then hang, leaving content stuck invisible
  • Leaving autoplaying GIFs and background video in place — neither reads the media query, so the one piece of motion the reader most wanted stopped keeps running

Related Terms

Put a file online in seconds

Drop in a document, an image, a page or a whole static website and share the link — free, with no build step and no server to set up.

Host a file free →