Who is harmed by motion on a page?
Movement draws the eye, which is why designers like it. For some people it does much more than that. People with vestibular disorders, which affect the inner ear and balance, can get dizzy, nauseous or develop a migraine from parallax scrolling, zooming transitions or content sliding across the screen. The effect can last hours after they close the page.
Others are affected in different ways. People with ADHD or some cognitive disabilities find it hard to read anything while something else moves nearby. People with low vision who zoom in may only see part of a moving strip at a time, and it slides away before they can read it. Screen magnifier users can lose their place entirely.
Flashing is the most dangerous case. Content that flashes more than three times a second can trigger seizures in people with photosensitive epilepsy. WCAG 2.2 treats this as level A, 2.3.1 Three Flashes or Below Threshold, and it is one of the few criteria that applies to every part of a page, even parts that otherwise do not need to conform.
What does `prefers-reduced-motion` do?
Every major operating system has a setting to reduce motion, in its accessibility or display settings. When someone turns it on, browsers report it through the prefers-reduced-motion media feature. Your CSS can check for the value reduce and remove or soften animation for those visitors.
The media query is a request, and you honour it by removing movement that is decorative or large: sliding, spinning, zooming, parallax, bouncing. You can keep small fades and colour changes, which rarely cause problems. Some teams write motion the other way round, adding animation only inside @media (prefers-reduced-motion: no-preference), so anyone whose browser does not report the setting gets the still version.
WCAG 2.2 has 2.3.3 Animation from Interactions at level AAA for motion triggered by scrolling or clicking. It is not usually required by law, and it is still the right thing to do for the people above.
@media (prefers-reduced-motion: reduce) {
.ticker p { animation: none; white-space: normal; }
}

Why does a moving strip need a pause button too?
Many people who are bothered by motion have never heard of the reduce motion setting, or use a borrowed or shared computer. WCAG 2.2 covers them with 2.2.2 Pause, Stop, Hide at level A: anything that starts moving on its own, lasts more than five seconds and sits alongside other content must have a way to pause, stop or hide it.
That applies to scrolling tickers, carousels that advance on their own, animated backgrounds and auto-updating feeds. The control must be easy to find and reach with a keyboard, so put it before the moving content in the source, where a keyboard user meets it first.
After the press, the button should say what it will do next. Changing the text from Pause offers to Play offers works. So does aria-pressed="true" on a button that keeps the name Pause offers: screen readers then say “Pause offers, toggle button, pressed”. Pick one approach and use it for every pause control on the site.
<button type="button" id="pause">Pause offers</button>
<div class="ticker" id="ticker"> ... </div>
<script>
pause.addEventListener('click', () => {
const paused = ticker.classList.toggle('paused');
pause.textContent = paused ? 'Play offers' : 'Pause offers';
});
</script>What about carousels and slideshows?
Auto-advancing carousels combine most of the problems on this page. They move without warning, they change content while people read, and the controls are often tiny arrows with no names. A screen reader user may hear the first slide and never learn there are four more.
If you need a carousel, start it paused or stop it as soon as it receives keyboard focus or the pointer. Give it a visible pause button, name the previous and next buttons, and say which slide is showing, for example with a heading per slide or text like “Slide 2 of 4”. Avoid announcing every automatic change with a live region, which would talk over the user every few seconds.
Often the better answer is no carousel: show the three offers as a short list. Everyone can read them, and the page is simpler to build.
Why is autoplaying sound a barrier?
A screen reader speaks through the same speakers as the page. When a video or audio track starts on its own, the two voices compete, and the user may be unable to hear the controls that would stop the noise. WCAG 2.2 1.4.2 Audio Control, level A, requires a way to pause or stop any audio that plays automatically for more than three seconds, or to turn its volume down separately.
The simplest fix is not to autoplay. Add controls and let people press play. If a background video must start on its own, give it muted, playsinline and a visible pause button, and make sure it stops after a short loop or can be stopped.
Most browsers now block autoplay with sound unless the user has interacted with the site, but you cannot rely on that: settings vary, and a visitor who clicked once may get the sound on the next page.
- Sound never starts on its own
- Muted background video has a pause control
- Video with speech has captions, and a transcript nearby
Is smooth scrolling a problem?
Smooth scrolling, from scroll-behavior: smooth in CSS or behavior: 'smooth' in script, animates the page when someone follows an in-page link. For a short distance it is harmless. On a long page it sweeps the whole screen past the reader, which is exactly the kind of large motion that triggers vestibular symptoms.
Put it inside a prefers-reduced-motion: no-preference query so it only happens for people who have not asked for less motion. The same goes for parallax effects, scroll-triggered animations and elements that fly in as you scroll. The checker in this course looks for CSS animations without a reduced motion rule; transitions and scroll effects need your own review.
@media (prefers-reduced-motion: no-preference) {
html { scroll-behavior: smooth; }
}How do you test motion settings?
Turn on reduce motion in your operating system settings and reload the page. Animations covered by your media query should stop. Browser developer tools can also emulate the setting without changing your system: look for the rendering or media emulation panel and set prefers-reduced-motion to reduce.
Then turn the setting off and test the pause control with the keyboard only. Tab to it, press Enter, and check the movement stops and the button’s name or state changes in the Screen reader view. For flashing, avoid it. If a video or animation might flash, run it through a photosensitive epilepsy analysis tool before publishing.
Check my work tests both halves here: the Checks for the media query, and a press on the button for the pause.
What do AI tools get wrong about motion?
AI generated landing pages love animation: fade-in-up on every section, bouncing call-to-action buttons, auto-rotating testimonial carousels and hero videos with autoplay and no muted. Almost none of them include a prefers-reduced-motion rule unless you ask.
When they do add one, it is often a blanket rule that sets every animation and transition duration to 0.01ms with !important. That stops most movement, and the tiny duration is chosen so animationend events still fire. A hand-written animation: none is what can stop those events and leave menus that never open, and the blanket rule also freezes spinners that tell people something is loading. Check that the page still works with the setting on.
Read the CSS for animation, transition on transform, and scroll-behavior, and the HTML for autoplay. Each one needs either a reduced motion rule, a pause control, or a good reason to stay.
Field notes
- Moving content can make some people dizzy or unable to read.
- The
prefers-reduced-motionmedia query follows the reduce motion system setting. - A pause button helps people who never changed that setting.
- Sound should never start playing on its own.
Easy to get wrong
Sound that starts on its own talks over screen readers and startles everyone. Let people choose to play it.
Moving content needs both: a setting-based fix for people who have asked for less motion, and a pause button for everyone else.
Keyboard and screen reader users meet content in source order. A pause button at the end means sitting through the movement to find it.
Questions people ask
Does reduce motion mean no animation at all?
No. It means removing movement that can cause harm: large slides, spins, zooms and parallax. A gentle fade or a colour change on hover is usually fine. Ask what a person with vertigo would feel.
Is an animated GIF covered too?
Yes. A GIF that loops for more than five seconds is moving content under 2.2.2. Use a still image, a short GIF that stops, or a video with controls.
Can I detect reduced motion in JavaScript?
Yes, with matchMedia('(prefers-reduced-motion: reduce)'). Check its matches property before starting script-driven animation, and listen for its change event in case the setting changes.
What counts as flashing?
A pair of opposing changes in brightness, especially to and from red. More than three in any one second, over a large enough area, fails 2.3.1. The safest design has no flashing at all.