Accessibility Certified – Home

Carousel: if people cannot stop it, you have lost them

Auto-rotating sliders are a barrier for many people: they read more slowly than the slides change, or the motion distracts. An accessible carousel can be paused and operated slide by slide.

2.2.22.1.14.1.21.4.112.4.7

Live demo

This demo is checked with axe-core without violations and fully operable by keyboard.

Try it with the keyboard: Tab, Enter, Space, the arrow keys and Escape. With a screen reader on, you hear what gets announced.

1 of 4

Contrast first

Body text needs a contrast ratio of at least 4.5:1 against its background.

The live demo needs JavaScript. Code and requirements are below.

Keyboard interaction

Tab
Reaches pause, previous and next, and links on the visible slide. Focus inside the carousel stops the autoplay.
Enter / Space
Pauses or plays, changes the slide.

When to use this pattern

First ask whether you need a carousel at all. Important content on the second or third slide often goes unseen. Several cards side by side or stacked are usually the better choice.

If it has to be a carousel: when it moves automatically for more than five seconds, 2.2.2 Pause, Stop, Hide requires a way to pause it. Our demo carousel does not start by itself if your system is set to reduce motion, and it stops as soon as it receives focus or the pointer.

Roles, states and properties

  • A container with aria-roledescription="carousel" and a name (aria-label).
  • Each slide: role="group", aria-roledescription="slide" and aria-label="2 of 4".
  • The pause button is the first control in the carousel and has a visible label that changes (“Pause” / “Play”).
  • The slide area has aria-live="off" while rotating and aria-live="polite" when paused, so manual changes are announced.
  • Slides that are not shown are hidden with hidden.

Keyboard interaction

KeyEffect
TabReaches pause, previous and next, and links on the visible slide. Focus inside the carousel stops the autoplay.
Enter / SpacePauses or plays, changes the slide.

Code

HTML and JavaScript (shortened)
<section aria-roledescription="carousel"
  aria-label="News">
  <button type="button" data-pause>Pause</button>
  <button type="button" data-prev>Previous slide</button>
  <button type="button" data-next>Next slide</button>
  <div aria-live="off">
    <div role="group" aria-roledescription="slide"
      aria-label="1 of 3">…</div>
    <div role="group" aria-roledescription="slide"
      aria-label="2 of 3" hidden>…</div>
  </div>
</section>

// No autoplay with reduced motion
const still = matchMedia(
  '(prefers-reduced-motion: reduce)').matches;
if (!still) start();

Common mistakes

  • No pause button, or one that only shows on hover.
  • Arrow buttons with an icon but no accessible name.
  • Automatic rotation that announces every slide through a live region, constantly interrupting screen reader users.
  • Hidden slides stay focusable, so focus disappears into invisible links.

Related WCAG criteria

Sources

Are your components built like this?

The free check finds many issues automatically. In the audit a person tests every component with a keyboard and a screen reader.

Free checkSee our method