Accessibility
Autoplay and prefers-reduced-motion
Autoplay over five seconds breaks WCAG 2.2.2 unless a stop control exists; prefers-reduced-motion adds the user's own preference, in CSS and in JavaScript.
Key points
- Success criterion 2.2.2 (Level A) requires a pause control for content that moves on its own for more than five seconds.
- The prefers-reduced-motion query stops CSS animation only: JavaScript timers keep running.
- Pages with JavaScript carousels average more errors than the sample, but that is a correlation, not a cause.
A video or carousel that starts on its own and keeps moving for more than five seconds breaks success criterion 2.2.2 (Level A), unless the user can stop it. The defence has two parts: a visible pause control and a prefers-reduced-motion query that honours people who asked for less motion.
What criterion 2.2.2 asks
The criterion covers any information that moves, blinks or scrolls on its own, lasts more than five seconds and sits next to other content: it needs a mechanism to pause, stop or hide it. Audio that starts automatically and runs past three seconds falls under criterion 1.4.2 instead: you need a volume or stop control, separate from the system one. WCAG 2.2 is a W3C Recommendation dated 5 October 2023, published under the W3C Document License.
The query only turns off CSS
This rule is the starting point, not the solution: it zeroes durations and iteration counts so an animation never plays even once. Watch animation-delay: if you do not zero it, an element can stay invisible while the animation waits.
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-delay: 0s !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
A carousel driven by setInterval keeps rotating: CSS never sees it. Read the same preference in JavaScript with matchMedia and listen to the change event, so someone who changes the setting with the page open does not have to reload.
const motion = window.matchMedia('(prefers-reduced-motion: reduce)');
let timer = null;
function sync() {
if (timer) clearInterval(timer);
timer = null;
if (motion.matches) return; // no rotation, the list stays still
timer = setInterval(nextSlide, 6000);
}
motion.addEventListener('change', sync);
sync();
Video: the part no CSS covers
A video with autoplay and sound starts anyway, whatever the preference says. Remove autoplay, or start muted with muted and playsinline, add an always-visible pause button and never resume playback when the pointer leaves. The control must live in the DOM, not only in the browser's native interface.
The carousel that holds up
- Always-visible pause: not only on pointer hover, because keyboard users never hover.
- Stop on focus: when focus enters the carousel the rotation stops, and it does not resume while focus stays inside.
- A static list for informational content: three cards in a grid read in one pass, a carousel hides them.
- No continuous announcement: a live region on an automatic carousel interrupts the screen reader every few seconds.
The EneUI catalogue
EneUI indexes the animation category and the hero blocks, where autoplay shows up most often. A verified record is Cult UI's 3d carousel, with an MIT licence declared upstream: the motion lives inside the component, so gate it on the preference instead of stripping it by hand. Checked on 1 November 2026 against 111,985 components.
The limitation
The query reflects a system setting that many people do not know they have, and it does not cover video, canvas or animation inside a third-party iframe. It is not an accessibility switch: it is a signal to honour alongside the pause control. DevTools emulation checks the CSS, not what the timers do.
Where to continue
The carousel pattern built on scroll snap is in carousels with CSS scroll snap; the motion utilities in Tailwind, including the preference variants, are in animation in Tailwind. The comparison of animation libraries, with licences and weight, is in the best animation libraries.
Frequently asked questions
How long can an animation run before it breaks 2.2.2?
Five seconds or less, when it starts on its own and sits next to other content. Below that threshold the criterion does not apply, but the user preference still does.
Does prefers-reduced-motion stop video as well?
No. The query concerns CSS. A video with the autoplay attribute keeps playing: remove the attribute or add a visible pause control.
Should I remove every animation?
No. Reduce the movement, not the interface: short transitions, no large motion, no parallax. Content and state must stay readable.
Are automatic carousels always wrong?
No, but an informational carousel works better as a static list. If it stays automatic, add an always-visible pause, stop on focus and no change under the pointer.
How do I test the preference without changing system settings?
With DevTools emulation: Rendering, Emulate CSS media feature prefers-reduced-motion. It covers CSS, not JavaScript timers.