← All Carousels

react-responsive-carousel

Summary

Accessibility Analysis

Score: 100% — All 22/22 accessibility issues resolved Median resolution time: 259.6 days

Caveat

100% score is misleading — the closed issues reveal poor accessibility architecture in the library. Known problems:


Implementation Notes

Use custom controls instead of built-in showIndicators and showArrows to avoid a11y issues.

The Problem with Built-in Controls

The library’s showIndicators prop renders pagination as:

<ul class="control-dots">
  <li role="button" class="dot">...</li>  <!-- Invalid ARIA! -->
</ul>

Using role="button" on <li> elements is invalid. Buttons should be <button> elements.

Our Approach

Disable built-in controls and implement custom ones:

<Carousel
  selectedItem={currentSlide}
  onChange={setCurrentSlide}
  showArrows={false}
  showIndicators={false}
  showThumbs={false}
  showStatus={false}
  infiniteLoop={true}
>
  {/* slides */}
</Carousel>

{/* Custom prev/next buttons */}
<div className="flex justify-center gap-4 mt-4">
  <button onClick={prev}>Previous</button>
  <button onClick={next}>Next</button>
</div>

{/* Custom dots with proper ARIA */}
<div className="flex justify-center gap-2 mt-4">
  {slides.map((_, i) => (
    <button
      key={i}
      onClick={() => goTo(i)}
      aria-label={`Go to slide ${i + 1}`}
      aria-current={i === currentSlide ? 'true' : undefined}
    />
  ))}
</div>

Container Accessibility

Added to our implementation: