Auto-rotating carousels and scrolling tickers are the canonical 2.2.2 failure: motion starts on load, runs past the five-second threshold, and ships without a pause, stop, or hide control.
2.2.2 Pause, Stop, Hide
In Plain Language
2.2.2 Pause, Stop, Hide (Level A) governs two distinct categories of unsolicited motion, each with its own threshold[1]:
- Moving, blinking, or scrolling content that (a) starts automatically, (b) lasts more than five seconds, and (c) is presented in parallel with other content must expose a mechanism to pause, stop, or hide it. Auto-rotating hero carousels, scrolling news tickers, and looping background animations are the canonical failures.
- Auto-updating content (live stock feeds, activity streams, chat logs) that starts automatically and runs in parallel with other content must expose a mechanism to pause, stop, hide, OR control the update frequency. There is no five-second grace period here -- a ticker that updates every two seconds is in scope from the first tick.
The exception is narrow: motion is exempt only when it is essential to the activity -- a loading spinner that resolves inside five seconds, or media the user explicitly opted into. "It looks nicer with motion" does not qualify.
Do not confuse 2.2.2 with 2.3.1 Three Flashes or Below Threshold, which handles seizure risk from high-frequency flashing. 2.2.2 is about cognitive distraction and loss of focus; 2.3.1 is about photosensitive epilepsy.
Why It Matters
- Users with cognitive and learning disabilities -- including ADHD and autism -- involuntarily track peripheral motion. A looping carousel in the viewport pulls attention off the primary text and resets reading position every rotation[1].
- Users with vestibular disorders can experience nausea, dizziness, and disorientation from large parallax effects and full-viewport animation. Without a stop control, the only remediation is to leave the page.
- Screen-reader users hit a different failure mode: an
aria-liveregion that auto-updates under the reading cursor interrupts the current utterance and can reorder what gets announced. A pause control lets the user stabilise the region before navigating into it. - Low-literacy readers need time to decode text. A news ticker that scrolls faster than comfortable reading speed is unreadable for the users who most need the content delivered plainly.
Examples
Auto-rotating carousel:
<button aria-label="Pause carousel">Pause</button>
Slide 3 of 5 -- auto-advances every 6 seconds
✔ Visible pause button lets users stop the automatic rotation
<div role="region" aria-label="Featured stories"
aria-roledescription="carousel">
<button aria-label="Pause carousel"
onclick="togglePause()">
Pause
</button>
<div aria-live="off">
<!-- aria-live set to "off" when paused,
"polite" when auto-advancing -->
Slide 3 of 5
</div>
</div>
Live activity feed:
<button>Pause updates</button>
New comment from Alex -- 2s ago
File uploaded by Jordan -- 15s ago
✔ Users can pause the auto-updating feed to read at their own pace
<section aria-label="Activity feed">
<button onclick="toggleFeedUpdates()">
Pause updates
</button>
<div aria-live="polite" aria-atomic="false">
<!-- New items are announced when
auto-update is active -->
<p>New comment from Alex -- 2s ago</p>
<p>File uploaded by Jordan -- 15s ago</p>
</div>
</section>
Decorative background animation:
<div class="animated-bg"></div>
// Runs continuously with no pause or stop
✘ Moving content plays indefinitely with no way for the user to pause, stop, or hide it
Scrolling news ticker across page header:
<marquee>Breaking: ...</marquee>
// Uses deprecated marquee element
// No pause, stop, or hide mechanism
✘ Scrolling text runs continuously -- users cannot pause or stop it to read the content
How to Fix It
- Ship a visible pause control on every auto-rotating carousel and hero. A keyboard-reachable
<button>labelled "Pause" (toggling to "Play") that halts the rotation and freezes the current slide is the canonical 2.2.2 fix. The control must be discoverable before the five-second threshold expires -- do not hide it behind a hover or a settings panel. - Gate CSS and JS animation behind
prefers-reduced-motion. Wrap keyframe animations, parallax effects, and auto-advancing transitions in@media (prefers-reduced-motion: reduce)and disable or shorten them. This satisfies vestibular-disorder users at the OS level without requiring them to find a site-specific control. - Delete any remaining
<marquee>. The element is obsolete in the HTML Living Standard and offers no pause affordance. Replace with static text, or with a controlled animation that has an explicit stop button. - Make auto-updating regions opt-in, not opt-out. Dashboards, activity feeds, and tickers should start paused (or update on user action) and announce new items through an
aria-live="polite"region only when the user has chosen to subscribe to updates. A pause button that togglesaria-livebetweenpoliteandoffkeeps the screen-reader experience coherent. - Replace auto-playing GIFs with a play-on-request pattern. Use a static poster frame with a play button, or the
<video>element withcontrolsand withoutautoplay. Animated GIFs cannot be paused by the user agent and fail 2.2.2 by construction once they run past five seconds.
References
- [1] W3C (2023). Understanding Success Criterion 2.2.2: Pause, Stop, Hide. W3C, Accessed 2026-04-07. https://www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide.html ↩ ↩