eBay

Carousel

Slideshow carousel of daily deals

Introduction

Creates a viewport around a list of items, where n items are visible at any time. We say that each viewport of items constitutes a slide.

Two pagination buttons ('Previous' & 'Next') will move to the previous slide or next slide respectively. Extra controls may allow access to specific slides.

There are two variants of carousel:

  • A carousel with one item in the viewport is a Slideshow Carousel (pictured above).
  • A carousel with more than one item in the viewport is a Filmstrip Carousel (pictured below).

Filmstrip carousel of daily deals

Working Examples

You can take a look at the carousel pattern in action on our examples site.

You can get an idea of the required markup structure by viewing our bones site.

Terminology

Viewport
Visible content area of the carousel. Displays a single slide.
Slide
Contains one or more items.
Item
A discrete unit of content inside of a slide (e.g. a tile or image)
Peek
A partially visible preview of an item on the next or previous slide. Peeks serves as a visual indicator that more slides exist. A non-visual equivalent would be the active (or non-"aria-disabled") state of the previous or next buttons.
Next Button
Moves to next slide
Previous Button
Moves to previous slide
Pagination Buttons
Move to specific slide. Also serve as visual indicators for total number of slides and current slide index
Pagination Bar
A scrollbar alternative to pagination buttons. Gives fuzzy visual indicator for total number of slides and current slide index

Best Practices

Carousel must have a heading. For example, "Trending Deals", "Watchlist".

Carousel heading should be postfixed with" - Carousel"; this text can be hidden offscreen.

Items must be marked up as a list.

Previous and next buttons must use button tags.

Pagination indicators must use button tags.

Viewport content must conform to accessibility guidelines.

Peeks must not be focusable or interactive.

If the slides can automatically progress, then the carousel must include a pause/play button.

  • Slideshow Carousels should not start automatically
  • Filmstrip Carousels must not start automatically
  • Pause/Play button should be the first interactive element in the carousel
  • Pause/Play button must always be visible
  • Automatic progression must pause when keyboard focus enters widget
  • Automatic progression must pause when mouse hovers over widget

Interaction Design

This section provides interaction design for keyboard, screen reader and pointing devices.

Keyboard

If "previous" button has focus, TAB key must move focus to first focusable element in view port.

If "next" button has focus, SHIFT+TAB key must move keyboard focus to last focusable element in view port.

Items offscreen, outside of view port, must not be keyboard focusable. Keyboard user must use 'Previous' and 'Next' buttons to control the viewport.

When on first slide, the 'Previous' button should remain in tab-order but must be visually disabled.

When on last slide, the 'Next' button should remain in tab-order but must be visually disabled.

Keyboard focus order summary

  1. Pause/Play button, if the carousel can auto-progress
  2. Previous button
  3. Controls (links, buttons, etc) belonging to items visible in the viewport
  4. Next button
  5. Pagination buttons or pagination bar, if they exist

Focus management summary

  • Activate previous or next button: focus must stay on Previous or Next button.
  • Activate Pause/Play button: focus must stay on the Pause/Play button.

Screen Reader

"Next" button must be announced as “Next slide - Carousel Heading”, or words to those effect.

"Previous" button must be announced as “Previous slide - Carousel Heading”, or words to those effect.

Items outside of the viewport must not be reachable with the virtual cursor.

When on first slide, screen reader must announce "Previous" button as disabled.

When on last slide, screen reader must announce "Next" button as disabled.

When moving virtual cursor from item to item, screen reader might announce list index position.

If pagination buttons are used, slide index and count must be announced when slide changes. Example: "Trending Deals - slide 4 of 6".

If slide is updated automatically (i.e. autoplay) the update must be announced. Example: “Slide 4 of 6 - Trending Deals”, or “Slide updated - Trending Deals” if no pagination buttons present.

Play button label must be “Play - Trending Deals”, or words to that effect.

Pause button label must be “Pause - Trending Deals”, or words to that effect.

Pointer

Clicking "Next" must update viewport with next slide.

Clicking "Previous" must update viewport with previous slide.

Clicking pagination button or pagination bar must update viewport with respective slide.

Developer Guide

Our sample implementation follows the Progressive Enhancement strategy; we build in a layered fashion that allows everyone to access the content of the carousel.

The three layers are:

  1. Content (HTML)
  2. Presentation (CSS)
  3. Behaviour (JS)

The carousel content will be fully visible and accessible without CSS and JavaScript.

Content (HTML)

The goal of our content layer is to add the list of items.

As usual we begin with our root element:

<div class="carousel">
    <!-- content will go here -->
</div>

For the purposes of this example, all content will be rendered server-side. You may wish to consider lazy-loading the content with AJAX. If you do utilise lazy-loading, be aware that your content will not be available in a non-JavaScript scenario.

We are going to create a list of vintage video games for sale on eBay, so we add a heading of "Video Games".

The heading is also post-fixed with the clipped text, "Carousel". This additional contextual text lets non-sighted users know they are dealing with a carousel pattern.

<div class="carousel">
    <h2 class="carousel__title">Video Games<span class="clipped"> - Carousel</span></h2>
    <!-- content will go here -->
</div>

TIP: The clipped text should ideally be inserted on the client, with JavaScript. Because until JavaScript is ready, it is just a static list, not a carousel.

The buttons must be inserted before and after the items, acting as bookends for the items.

<div class="carousel">
    <h2 class="carousel__title">Video Games<span class="clipped"> - Carousel</span></h2>
    <button aria-label="Previous slide - Video Games" class="carousel__previous" disabled type="button"></button>
    <!-- items will go here -->
    <button aria-label="Next slide - Video Games" class="carousel__next" disabled type="button"></button>
</div>

Both buttons have a property of disabled. This property will be removed later with JavaScript.

TIP You may also wish to render the "Previous" and "Next" buttons on the client, using JavaScript.

A carousel can contain a list of anything, for example - tiles, images, videos, static text. For our example it will be a list of video games.

Each item will contain an image, heading, format, price + shipping.

<div class="carousel">
    <h2 class="carousel__title">Video Games<span class="clipped"> - Carousel</span></h2>
    <button aria-disabled="true" aria-label="Previous slide - Video Games" class="carousel__previous" type="button"></button>
    <ul>
        <li>
            <img src="horace.jpg" alt="" /><h4>
            <a href="http://www.ebay.com/sch/i.html?_nkw=Horace+%26+the+Spiders">Horace &amp; the Spiders</a></h4>
            <p>Spectrum 48K</p>
            <p>$4.99 - Free Shipping</p>
        </li>
        <li>
            <img src="dragon.jpg" alt="" /><h4>
            <h4><a href="http://www.ebay.com/sch/i.html?_nkw=Double+Dragon">Double Dragon</a></h4>
            <p>Spectrum 48K</p>
            <p>$4.99 - Free Shipping</p>
        </li>
        <li>
            <img src="dizzy.jpg" alt="" /><h4>
            <h4><a href="http://www.ebay.com/sch/i.html?_nkw=Treasure+Island+Dizzy">Treasure Island Dizzy</a></h4>
            <p>Spectrum 48K</p>
            <p>$4.99 - Free Shipping</p>
        </li>
        ...
    </ul>
    <button aria-label="Next slide - Video Games" class="carousel__next" type="button"></button>
</div>

Checkpoint (HTML)

Our content is in place. The carousel items are fully visible and accessible without CSS and JavaScript.

Again, if you consider this content non-important, you may wish to not use progressive enhancement and render the carousel in it's entirety on the client. I will also add, rather wryly, if the content is not important, then why render it at all.

Presentation (CSS)

The goal of the presentation layer is to present the list of items as a horizontal, scrollable layer. Yes - you heard me right - until JavaScript is available, we can rely on some old-fashioned scrollbar action to scroll the viewport.

This section is coming soon.

Behaviour (JS)

The visual goal of the behaviour layer is to replace the primitive horizontal scrollbar with custom slide transitions. These transitions are triggered with the "Previous", "Next" and pagination buttons (if they exist). On touch-screen devices these transitions are also triggered with swipe gestures.

The semantic goal is to ensure that no device is able to access items in any other slide than the current, active slide.

Implementing CSS transitions and swipe gestures are outside the scope of this guide. Instead, our main focus will be ensuring the robust, accessible state of the carousel.

Initial State

We assume the first slide will be the active slide, therefore the "Previous" button will be partially disabled.

What do we mean by partially disabled?

We say "partially" disabled when we want an inoperable button to remain keyboard focusable. The inoperable button must be aurally and visually disabled using ARIA (i.e. aria-disabled) and CSS (e.g. opacity) respectively.

Why leave the button keyboard focusable?

First of all, the button acts as a bookend, giving a strong clue to non-sighted users that they are dealing with a carousel when tabbing through page. If the button was not focusable, the user would tab straight into the first list item.

Secondly, these buttons may frequently flip back and forth between operable and inoperable; even while focus is on a button. If the button changes state to inoperable while focus is on the button, we want focus to remain in place rather than move somewhere unexpected.

<div class="carousel">
    <h2 class="carousel__title">Video Games<span class="clipped"> - Carousel</span></h2>
    <button aria-disabled="true" aria-label="Previous slide - Video Games" class="carousel__previous" type="button"></button>
    <!-- items will go here -->
    <button aria-label="Next slide - Video Games" class="carousel__next" type="button"></button>
</div>

This remainder of this section is coming soon.

ARIA Reference

This section gives an overview of ARIA usage within the context of the carousel pattern.

aria-disabled

Used to notify user that "Next" or "Previous" buttons are in a disabled state. Screen readers will announce 'disabled,' 'dimmed,' 'unavailable,' or words to that effect.

role=status

Used to create a live status region for updates to carousel viewport, e.g "Trending Deals - slide 4 of 6”.

results matching ""

    No results matching ""