Functionality

Status: This is not ready for detailed review. It is an in-progress, unapproved editor’s draft.

Provide functionality to display the carousel items one at a time, and to allow users to browse through them. This functionality is added using scripting, based structure of the elements involved.

Carousel items that are visually hidden should also be hidden from assistive technology, to avoid a mismatch between what is visually on the screen and what the user is interacting with. All carousel items that are not displayed visually are hidden by using the CSS display: none declaration. Refer to content hiding techniques for more background.

Scripted styling

In the example below, JavaScript is used to add the class name .active to the carousel container. The styling for this class positions all carousel items all on top of each other and hides them. The class name .current is added to the one carousel item that is to be displayed, which ensure that it is on top of all other hidden carousel items.

Code snippet: CSS
.active .slide {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  border: none;
}

.slide.current {
  display: block;
  z-index: 500;
}

The outcome looks like this:

Example:

Featured Articles:

Scripting is further used to add buttons that allow users to switch back and forth between carousel items. While these buttons often have various styles visually, it is useful to code them using <button> elements. This gives them semantic meaning and also makes them more compatible with assistive technology and keyboard use. Refer to keyboard accessibility for more background.

Toggle Buttons

In the example below, JavaScript is used to generate code for the buttons and insert them onto the carousel. These particular buttons are visually displayed as arrows that overlay the carousel items. The images use the alternative text that reads "Previous Slide" and "Next Slide".

A semi-transparent white background with black arrows was selected to ensure sufficient color contrast between the text and any background images in the carousel items. This is especially important for possibly noisy background images. Also, the buttons increase in size when users hover over them with the mouse to provide more click area for people with reduced dexterity. They also increase in size when they are focused by keyboard to better highlight to keyboard users where the current focus is.

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 Slide">' +
    '</button>' +
  '</li>' +
  '<li>' +
    '<button type="button" class="btn-next">' +
      '<img src="img/chevron-right.png" alt="Next Slide">' +
    '</button>' +
  '</li>';

  ctrls.querySelector('.prev').addEventListener('click', function(){
    prevSlide();
  });

  ctrls.querySelector('.next').addEventListener('click', function(){
    nextSlide();
  });

carousel.appendChild(ctrls);
Code snippet: CSS
  .btn-prev,
  .btn-next {
    position: absolute;
    z-index: 700;
    top: 50%;
    margin-top: -2.5em;
    border:0;
    background: rgba(255,255,255,.6);
    line-height: 1;
    padding:2em .5em;
    transition: padding .4s ease-out;
  }

  .btn-next:hover, .btn-next:focus,
  .btn-prev:hover, .btn-prev:focus {
    padding-left: 2em;
    padding-right: 2em;
  }

  .btn-prev {
    left:0;
    border-radius: 0 .25em .25em 0;
  }

  .btn-next {
    right:0;
    border-radius: .25em 0 0 .25em;
  }

The outcome looks like this:

Example:

Featured Articles:

Indicating the total number of carousel items and which one of them is currently being displayed helps users to orient themselves and find any information they need. Ideally this is done by a set of styled buttons that each represent a carousel item in the sequence. Providing these slide representations as buttons that can be activated allows users to browse more freely within the carousel items. Providing these buttons within a list, adds meaning and semantics to the content, such as the number and order of the carousel items.

In the following example, a list with buttons is added using JavaScrip and then styled to look visually like a progress indicator. The buttons are numbered matching the corresponding carousel items. The button corresponding to the currently displayed carousel item is highlighted both visually and using visually hidden text. Also the button that currently has the keyboard or mouse focus is highlighted.

Code snippet:
<ul class="slidenav">
  <li>
    <button class="current" data-slide="0">
      <span class="visuallyhidden">News</span> 1
      <span class="visuallyhidden">(Current Slide)</span>
    </button>
  </li>
  <li>
    <button data-slide="1">
      <span class="visuallyhidden">News</span> 2
    </button>
  </li>
  <li>
    <button data-slide="2">
      <span class="visuallyhidden">News</span> 3
    </button>
  </li>
</ul>
Code snippet: CSS
.slidenav button {
  border: 2px solid #036;
  background-color: #036;
  line-height: 1em;
  height: 2em;
  width: 2em;
  font-weight: bold;
  color: #fff;
}

.slidenav button.current {
  border-radius: .5em;
  background-color: #fff;
  color: #333;
}

.slidenav button:hover,
.slidenav button:focus {
  border: 2px dashed #fff;
}

.slidenav button.current:hover,
.slidenav button.current:focus {
  border: 2px dashed #036;
}
Example:

When users select a carousel item through the buttons in a carousel item indicator then the focus needs to be to the corresponding carousel item. The focus should not be set to the carousel item if the toggle buttons are used, as the user may want to skip over several carousel items quickly and would use the position otherwise.

Carousel items will often be coded using elements that, by default, are not focusable, such as <li> or <article> elements. Use the tabindex attribute with its value set to -1, to make such elements capable of receiving focus using JavaScript, then set the focus on them. Refer to Keyboard accessibility for more background.

Focus change

The code snippet below shows the JavaScript code used in the demo for this tutorial. It illustrates how the tabindex attribute and the focus are set when a carousel item is selected, and how the carousel item indicator is updated accordingly.

Code snippet: JavaScript
function setSlides(new_current, setFocus) {
  setFocus = typeof setFocusHere !== 'undefined' ? setFocusHere : false;

  new_current = parseFloat(new_current);

  var length = slides.length;

  slide[index].className = 'slide';
  slides[new_current].className = 'current slide';

  buttons[index].className = "";
  buttons[new_current].className = "current";

  if (setFocus) {
    // Only if the slide was directly
    // picked from the list of slides
    slides[new_current].setAttribute('tabindex', '-1');
    slides[new_current].focus();
  }

  index = new_current;
}

slidenav.addEventListener('click', function(event) {
  if (event.target.localName == 'button') {
    setSlides(event.target.getAttribute('data-slide'), true);
  }
}, true);

Putting it all together

The sample below is a demo of the carousel that we've built by putting together the previous examples. It is a working example of a carousel where one carousel item at a time is displayed. It includes buttons for users to toggle back and forth between the carousel items, and a carousel item indicator that allows users to view which carousel item they are currently viewing and to jump to other carousel items. Animating this carousel will be explained on the next page.

Example:

Featured Articles:

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)

  • 2.4.7 Focus Visible: Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible. (Level AA)

  • 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)