Provide functionality to select carousel items and to inform users about the change of carousel items.

Add previous and next buttons

Provide buttons to allow users to switch back and forth between items. Use <button> elements to provide semantic meaning, support for assistive technologies, and consistent keyboard behavior. Create and add the buttons using JavaScript, as they only work when JavaScript is available anyway.

Code snippet: JavaScript
var ctrls = document.createElement('ul');

ctrls.className = 'controls';
ctrls.innerHTML = '<li>' +
    '<button type="button" class="btn-prev">' +
      '<img src="img/chevron-left.png" alt="Previous Item">' +
    '</button>' +
  '</li>' +
  '<li>' +
    '<button type="button" class="btn-next">' +
      '<img src="img/chevron-right.png" alt="Next Item">' +
    '</button>' +

ctrls.querySelector('.btn-prev').addEventListener('click', function(){

ctrls.querySelector('.btn-next').addEventListener('click', function(){


Announce the current item

Use a WAI-ARIA live region to inform screen reader users what item is currently shown. In this example, a visually hidden, “polite” live region is used and added to the carousel when the carousel is loaded. Then, when clicking the previous or next buttons, the text “Item x of y” (with x for current item number and y for the number of items) is set to this live region. Capable screen readers will announce this text.

Allow the user to maintain control of the keyboard focus. When the carousel advances automatically, users should not be drawn away from their current place in the page. Also, do not move keyboard focus when the previous or next buttons are used; moving the focus makes it harder for users to browse back and forth between the slides.

Code snippet: Add a live region to the carousel
var liveregion = document.createElement('div');
liveregion.setAttribute('aria-live', 'polite');
liveregion.setAttribute('aria-atomic', 'true');
liveregion.setAttribute('class', 'liveregion visuallyhidden');
Code snippet: Change text in the liveregion to have that text announced
if (announceItem) {
  carousel.querySelector('.liveregion').textContent = 'Item ' + (new_current + 1) + ' of ' + slides.length;

Add navigation buttons

Display buttons for each item in the carousel and highlight the current item. This allows users to get an overview of the carousel content, where they are in the sequence and will enable them to navigate directly to any item.

The list with buttons in the example below is added using JavaScript, with a number on the button that corresponds to the carousel item. The buttons are numbered matching the corresponding carousel items. The button for the active carousel item is highlighted both visually, and by using text that is visually hidden (for screen readers).

Code snippet:
<ul class="slidenav">
    <button class="current" data-slide="0">
      <span class="visuallyhidden">News</span> 1
      <span class="visuallyhidden">(Current Slide)</span>
    <button data-slide="1">
      <span class="visuallyhidden">News</span> 2
    <button data-slide="2">
      <span class="visuallyhidden">News</span> 3

When users select an item with those navigation buttons, the focus should be set on the selected item. In this case, the focus needs to be set to the <li> element that has the class current set, after the change or transition. This makes interaction easier for keyboard and assistive technology users.

By default, <li> elements cannot receive focus. By setting its tabindex attribute to -1, the element is enabled to receive focus through JavaScript.

These tutorials provide best-practice guidance on implementing accessibility in different situations. This page combined the following WCAG success criteria and techniques from different conformance levels:

Success Criteria:

  • 1.3.1 Info and Relationships: Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text. (Level A)

  • 2.1.1 Keyboard: All functionality of the content is operable through a keyboard interface without requiring specific timings for individual keystrokes, except where the underlying function requires input that depends on the path of the user’s movement and not just the endpoints. (Level A)

  • 4.1.2 Name, Role, Value: For all user interface components (including but not limited to: form elements, links and components generated by scripts), the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to user agents, including assistive technologies. (Level A)