Accessibility

What Carousel does for you, and what it leaves to the page around it.

What it renders, and what it does not

Carousel renders plain <div>s, with no role, no aria-roledescription, no live region and no label. Nothing tells a screen reader that this is a set of slides, or that one changed. Add that around it.
  • Hidden slides keep their links in the tab order. Slides that are not current get aria-hidden, but a link or button inside them can still take focus. Track the index with afterChange and make the inactive slides inert, or keep slides free of controls.
  • infinite copies the slides at both ends, so an id or a control inside a slide exists more than once. A fade carousel makes no copies.

Autoplay, and what a pause control has to do

Anything that moves on its own for more than five seconds needs a way to pause, stop or hide it (WCAG 2.2.2). Carousel ships no such control.
  • It pauses on hover (pauseOnHover) but not on focus, so keyboard and touch readers cannot stop it. Turn on pauseOnFocus, and still add a pause button.
  • A pause control is a <button> beside the carousel whose name says what it does (“Pause slideshow”, then “Play slideshow”), and it keeps the carousel stopped.
  • Drive it through the ref, so pressing it does not make the slides jump.
  • The default 3000 milliseconds is too short to finish a sentence. Slow it down for slides with text.

The dots are real buttons

Each dot is a <button> named with its number (“1”, “2”, “3”), so the dot row works from the keyboard.
  • The current dot is shown by color and width only. A screen reader hears identical numbered buttons. Add aria-current="true" through customPaging when the dots are how readers navigate.
  • Use customPaging to give each dot a better name, like visually hidden “Go to slide 2 of 5”.
  • The hit area is larger than the painted dot, but the dot is still what a low-vision reader has to find.

Keyboard

Tab reaches the arrows and the dots, and Enter and Space press them. The arrows are named from the locale, “Previous slide” and “Next slide”.
  • Arrow keys mostly do not work. They only respond while something inside a slide has focus, not on the dots or the arrows. Do not tell readers to use them, and give the carousel visible Previous and Next buttons where stepping by keyboard matters.
  • A custom prevArrow or nextArrow loses the default label. Give it an aria-label, and spread the props it receives.

Announcing a change without interrupting

Nothing announces a slide change, so a screen reader user who presses Next hears nothing. Fix it from afterChange.
  • Put a visually hidden aria-live="polite" region outside the slides, and write “Slide 3 of 5” into it. Polite waits for a pause in speech. Assertive interrupts it.
  • It cannot sit inside a slide, because slides are hidden as they leave.
  • Do not announce from an autoplaying carousel. A message every three seconds makes the rest of the page unreadable.

Contrast, focus and motion

  • The focus ring is removed. The arrows brighten on focus, and the dots show no change at all. Add a :focus-visible outline to both.
  • The arrows are always white, at low opacity, whatever the theme. Over a light slide they fail contrast.
  • The resting dots are faint, drawn in the background color at low opacity. On a light slide the active dot may be the only one a low-vision reader sees. Recolor both over light content.
  • Autoplay ignores reduced motion. Carousel does not check prefers-reduced-motion, and neither a motion-safe: class nor the motion: false token stops it. Read the setting yourself and pass autoplay only when motion is welcome.