Skip to main content
Workforce LibreTexts

6.8: Carousels

  • Page ID
    15626
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)

    Carousels are typically used to present a series of panels or images that rotate at a particular frequency.

    WAI-ARIA roles, states, and properties used in carousels

    • role="region"
    • aria-live="polite"
    • tabindex="0"
    • aria-describedby="[id of div with instructions]"
    • aria-hidden="(true|false)"
    Suggested Reading: The Carousel Tutorial from the W3C provides additional details on constructing accessible carousels.

    The following JSFiddle presents a typical carousel widget. Review the JavaScript and HTML markup. Test the carousel presented under the Result tab with ChromeVox to understand how it functions without any accessibility features added. You can work in JSFiddle itself by clicking “Edit in JSFiddle.” Copy the accessibility/WAI-ARIA code described below to fix the accessibility of the accordion before completing Activity 11 on the page that follows.

    A link to an interactive elements can be found at the bottom of this page.

    Though instructions are not always required, they can be helpful for screen reader users when there is non-standard keyboard navigation. In our case, we’ll add a few words and assign them to the “instructions” variable in the default settings of the init() function for the carousel. The instructions will be rendered in its own <div> and referenced with aria-describedby a little later in the code.

    A link to an interactive elements can be found at the bottom of this page.

    We’ll define a few attributes when the carousel is initialized: give it a role="region" to add it to the landmarks, add a tabindex to make it keyboard focusable, and reference the ID of the instructions <div> with aria-describedby. Add keyboard operability with .on('keydown') and a reference to the onKeyDown function, described below.

    A link to an interactive elements can be found at the bottom of this page.

    Screen reader users will not need the Next/Previous controls, so hide them. They will be using the Arrow keys instead, defined in the onKeyDown function further below.

    A link to an interactive elements can be found at the bottom of this page.

    Hide images from screen readers. Notice that the alt text for the images are defined in the HTML but left empty so it is not read in this case. Screen readers will read the figcaptions.

    A link to an interactive elements can be found at the bottom of this page.

    Add screen reader instructions by generating a <div> that contains the instruction text defined earlier and hide the <div> by default. The instructions are read when the carousel receives focus, and the aria-describedby attribute is dynamically added to reference the instructions.

    A link to an interactive elements can be found at the bottom of this page.

    Add an aria-live attribute to the stopTimer function. Set its value to polite so content updating in the live region announces when a screen reader is not reading elsewhere on the page. The content of the visible carousel panel is read automatically when it is in focus, manually navigating between panels with the Arrow keys.

    A link to an interactive elements can be found at the bottom of this page.

    Remove the live region when focus on the carousel is removed in the startTimer function. By doing so, the live region stops reading when the timer is reactivated onblur, and it does not interfere with the screen reader reading elsewhere on the page.

    A link to an interactive elements can be found at the bottom of this page.

    Hide the active slide from screen readers with aria-hidden="true". Then, make the next slide visible to screen readers with aria-hidden="false" in the gotoSlide function.

    A link to an interactive elements can be found at the bottom of this page.

    Adding Keyboard Operability

    Add keyboard operations for the carousel, pulling keyboard events from ik_utils.js to use Left and Right arrows for moving between panels in the carousel, and the Esc key to exit the carousel and resume automatic rotation.

    A link to an interactive elements can be found at the bottom of this page.

    Accessible Carousel in Action

    Watch the following video to see how ChromeVox interacts with a carousel. The carousel rotates automatically when focus is elsewhere on the page. When it receives focus, rotation stops, and navigation instructions are read. The Left and Right arrow keys are used to move manually between panels in the carousel while it has focus. The contents of each panel are read through a live region, dynamically added to the main container <div> when the carousel has focus. Using the Tab key while the carousel has focus sends focus to any focusable element within the panel that is in view, a link to the person who shared the photo in this case. Aim to have the carousel you update in the activity on the following page operate and announce like the one in the video.

    Video: Accessible Carousel

    Thumbnail for the embedded element "Accessible Carousel"

    A YouTube element has been excluded from this version of the text. You can view it online here: https://pressbooks.library.ryerson.ca/wafd/?p=362


    This page titled 6.8: Carousels is shared under a CC BY-SA license and was authored, remixed, and/or curated by Digital Education Strategies, The Chang School.

    • Was this article helpful?