AccessScanRun a free scan

Guide

How to Build an Accessible Carousel: Pause Controls, Keyboard Operation, and WCAG 2.2.2

Carousels are one of the most-shipped and most-broken components on the web. An accessible carousel is not about removing the slider; it is about giving people control over motion, making every control reachable by keyboard, and never moving content out from under someone who is reading or interacting with it.

The rule that trips up most implementations is WCAG Success Criterion 2.2.2 Pause, Stop, Hide (Level A): any content that moves, blinks, scrolls, or auto-updates, starts automatically, lasts more than five seconds, and is presented alongside other content must let users pause, stop, or hide it. An auto-rotating hero slider is the textbook example. This guide covers the autoplay rule, keyboard interaction, focus management, and the smaller WCAG 2.2 criteria that carousels routinely fail.

Why auto-advancing content needs controls (WCAG 2.2.2)

2.2.2 exists because motion is hostile to a surprising range of users. Someone using a screen magnifier loses their place when the slide changes. A person reading slowly, or using a switch device, cannot finish before the next panel replaces the text. People with vestibular or attention-related conditions are actively distracted or made unwell by movement they did not ask for. The criterion does not forbid autoplay; it forbids autoplay you cannot stop.

The three escape hatches in the name are alternatives, and you only need one: pause (freeze and resume), stop (end the motion for the session), or hide (remove the moving content entirely). For a carousel, a visible Pause/Play toggle is the most practical. It must be a real <button>, reachable by keyboard, with an accessible name that reflects its current state, for example toggling between "Pause slideshow" and "Play slideshow".

Two carve-outs are worth knowing. Motion that lasts five seconds or less is not covered, so a one-time intro animation does not need a control. And prefers-reduced-motion is not a substitute for 2.2.2; it is a complement. Respecting the OS setting should mean autoplay never starts, but you still owe a pause control to everyone whose system does not request reduced motion. The criterion is part of WCAG 2.2 Level A, the baseline the European Accessibility Act enforces via EN 301 549 from 28 June 2025.

Pause, stop, and the autoplay timer

A correct pause control does two things: it visibly stops the rotation, and it actually clears the timer rather than just hiding the next frame. The common bug is a button that swaps an icon but leaves setInterval running, so slides keep advancing behind the scenes and focus or live regions still fire.

Beyond the explicit button, the autoplay timer should yield to user attention automatically. Stop advancing when:

  • The pointer is hovering the carousel (mouseenter pauses, mouseleave may resume).
  • Keyboard focus moves anywhere inside the carousel (focusin pauses, focusout resumes only if the pointer is also away).
  • The user has activated any control, such as a next/prev arrow or a dot, signalling they are now driving manually.
  • prefers-reduced-motion: reduce is set, in which case autoplay should not start at all.

Tie the timer to the document's visibility too: pause on visibilitychange when the tab is hidden so the slideshow is not silently churning. The logic that prevents content shifting while it is being read is the same logic that keeps you compliant with 2.4.11 Focus Not Obscured (Minimum), since a slide that advances under a focused control can hide that control from view.

Keyboard operation and focus management

Every interactive part of the carousel, the previous and next arrows, the slide-picker dots, the play/pause toggle, and any links or buttons inside a slide, must be operable with Tab and Enter or Space. Build them as native <button> and <a> elements. If you reach for a <div>, you are signing up to re-implement focusability, Enter/Space handling, and a role by hand, and it will usually be wrong.

The decisive detail is what happens to slides that are not currently visible. Offscreen slides must be removed from the tab order, otherwise keyboard users tab into invisible content and lose track of where focus is. Use aria-hidden="true" on inactive slides and ensure their focusable descendants are taken out of the tab sequence, for example by toggling inert, or tabindex="-1" plus aria-hidden. When the active slide changes, focus should stay on the control the user activated and never jump to the new slide unexpectedly.

Two patterns dominate. A basic region pattern wraps slides in a labelled region (a role="group" or <section> with aria-roledescription="carousel"), exposes arrow buttons, and announces the current position. A tabbed pattern treats the dots as role="tablist" and slides as role="tabpanel", where Left/Right arrow keys move between tabs. Pick one and follow the ARIA Authoring Practices for it consistently; mixing them produces a confusing experience for screen reader users.

Screen reader announcements and ARIA

Carousels create a live-region trap. If you put aria-live="polite" on the slide container while autoplay is running, every automatic rotation announces itself, flooding the screen reader user with interruptions. The fix: keep the slide container passive during autoplay, and only switch to aria-live="polite" once the user has paused and is manually stepping through slides. That way arrow-key navigation is announced, but auto-rotation is not.

Label the carousel as a whole with aria-label or aria-labelledby so it is discoverable in the regions list. Give each slide an accessible name and an aria-roledescription of "slide" where appropriate, and expose position with visible or programmatic "3 of 6" text. Images inside slides need real alternative text, not empty or decorative alt, when they carry the message.

The WCAG 2.2 criteria carousels quietly fail

Beyond 2.2.2, WCAG 2.2 added requirements that hit carousel controls specifically:

  • 2.5.8 Target Size (Minimum), AA asks for at least 24 by 24 CSS pixels. Tiny dot indicators are the classic failure; give each dot a 24x24 hit area even if the visible dot is smaller, and space them apart.
  • 2.5.7 Dragging Movements, AA means any swipe-to-advance gesture must have a non-drag alternative, which your arrow buttons already provide as long as they are not hidden on touch.
  • 2.4.11 Focus Not Obscured (Minimum), AA means a focused arrow or dot must not be fully hidden by a sticky header or by an advancing slide overlay.
  • 1.4.3 / 1.4.11 Contrast requires 4.5:1 for normal text in slides, 3:1 for large text (at least 18pt, or 14pt bold) and for the controls themselves as UI components. Light arrows over a bright photo are a frequent miss; verify with a contrast checker.

Before you ship, run the page through a free scan to catch missing labels, contrast failures, and controls without accessible names: scan your site with AccessScan. Pair the automated pass with a manual keyboard and screen reader check, since no scanner can confirm that focus order and announcements feel right, and many of these carousel rules can only be judged by hand. For the full criteria list and conformance levels, see the WCAG reference.

Check your site against AccessScan

See your issues ranked by impact in seconds — free.

Run a free accessibility scan

FAQ

Does WCAG 2.2.2 ban auto-advancing carousels?

No. The criterion permits motion that starts automatically, lasts more than five seconds, and runs alongside other content, as long as users can pause, stop, or hide it. An auto-rotating carousel is compliant if it has a working pause control. The violation is auto-advancing with no way to stop it.

Is a pause button enough, or do I also need to stop autoplay on hover and focus?

A reliable pause control is what 2.2.2 strictly requires. But auto-advance that keeps moving while someone reads or interacts causes failures elsewhere, such as yanking focus or hiding a control before it can be activated. Best practice is to pause on hover, on focus within the carousel, and when prefers-reduced-motion is set, in addition to the explicit button.

What ARIA role should a carousel use?

There is no dedicated carousel role. A common pattern is a labelled region or group with aria-roledescription of 'carousel', slides as a list or as tabpanels, aria-live='polite' on the slide container only while autoplay is paused, and aria-hidden plus removal from the tab order on offscreen slides. Avoid making non-visible slides focusable.

Do carousel arrows and dots need a minimum size?

Under WCAG 2.2, Target Size (Minimum) 2.5.8 (AA) asks for at least 24 by 24 CSS pixels, with exceptions for inline and spaced targets. Small dot indicators are a frequent failure. Give each control a 24 by 24 pixel hit area even if the visible dot is smaller, and keep adequate spacing between them.

How should the autoplay timer behave when someone interacts with a slide?

Stop it. If a user tabs into the carousel, hovers it, or activates a control, the auto-advance should pause so the slide does not change under them. Restarting only on explicit action, or on mouse-leave combined with no keyboard focus inside, prevents content shifting while it is being read or operated.

More guides