Carousels

Introduction

While carousels are a popular component on websites, there’s plenty of evidence to suggest that they are an ineffective method of displaying content – with few people looking beyond the first one or two slides.

Basic rules around carousels

If designing a carousel is unavoidable, these are the basic rules we should follow to make sure they are accessible:

  • Auto-rotating carousels must be able to be paused or stopped.
  • All controls for pausing / stopping / changing the current slide within a carousel must be keyboard accessible.
  • The order of the content is logical.
  • Users are made aware when the particular slide on display is replaced with another.

Implementing an accessible carousel

There are a number of ways that carousels can be implemented accessibly. One way is the draft WAI-ARIA Authoring Practices Carousel.

Elements

This pattern makes use of a <section> element with an aria-role description="carousel" attribute to contain the carousel, and each slide within the carousel marked up as a <div> with a role="group" attribute, aria-roledescription="slide" attribute, and an aria-label attribute value that indicates the position of the slide within the set, for example aria-label="1 of 4".

The slides are wrapped in a <div> element with a live-region="polite" attribute.
All slides, except for the currently visible slide, are hidden with CSS style display: none; or the hidden attribute, thereby hiding the slides both visually and from assistive technologies and removing interactive within the hidden slide from the keyboard tab order.

Buttons

Buttons to move forward and backwards precede the slides. When a slide is changed using these buttons the new slide content is announced via the live region. Because the buttons come before the slides, a keyboard user can tab to the content immediately following the buttons to interact with the content.

Variations on the pattern

Some changes from the WAI-ARIA pattern are recommended, notably replacing the links with a role="button" attribute to native <button> elements, and replacing the <div> elements that contain the slides with an unordered or ordered list, thereby allowing progressive enhancement from a list of elements to a carousel, as follows:

Code sample: carousel example

<section aria-roledescription="carousel" aria-label="[Description of carousel contents]">
  <ul>
    <li><button aria-pressed="false">Play automatic slide show</button></li>
    <li><button aria-controls="carousel-items">Previous slide</button></li>
    <li><button aria-controls="carousel-items">Next slide</button></li>
  </ul>
  <ul role="presentation" aria-live="polite">
    <li role="group" aria-roledescription="slide" aria-label="1 of 4">
      <!-- Slide content -->
    </li>
    <li role="group" aria-roledescription="slide" aria-label="2 of 4" hidden>
      <!-- Slide content -->
    </li>
    <li role="group" aria-roledescription="slide" aria-label="3 of 4" hidden>
      <!-- Slide content -->
    </li>
    <li role="group" aria-roledescription="slide" aria-label="4 of 4" hidden>
      <!-- Slide content -->
    </li>
  </ul>
</section>

Things to check

Have you?

  • Checked to see whether there is any other way to present this content?
  • Checked all aspects of the carousel can be accessed by keyboard users and screen readers?
  • Made sure the user is able to stop any automatic rotation of slides?
  • Made only one slide is visible at any one time?
  • Checked the carousel buttons have useful labels and good colour contrast?
  • The carousel buttons come before the slides in the visible and source order of the content.

WCAG criteria

Did you find this page helpful?