Accessible Carousels
Carousels are a list of content panels that mouse user can cycle through using arrow controls and panel indicator. Usually carousels show only one panel at a time, and they usually (but not always) have at least one CTA in them. They exist to cram as much content in the valuable "Above The Fold" real estate on websites. Although it is debatable whether "Above The Fold" is as important as people think it is, it is still a solid requirement for a lot of website owners.
In our opinion, carousels are a hack designed to cram a huge amount of content within a small amount of space. There are better alternatives to carousels out there, and these articles are a good place to start if you are looking for them:
- 5 Alternatives to Using a Carousel on Your Website Homepage
- More Alternatives to Using a Carousel on Your Website
- Alternatives to carousels in web design
That said, there are times when as a web developer you are asked upon implementing an accessible one. On this page are two ways of implementing accessible carousels: one solution is good when you know there will be at least one interactive control in each panel, and the other is good when you cannot make that guarentee. Note that all the carousels on this page use Glider.js, but the code walkthrough below will contain information developers need to implement accessible carosuels regardless of the carousel frameworks being used. If the developer is making a carousel from scratch, they can use the NPM module that makes Glider.js accessible (see below).
Solution 1: Treat The Carousel Like A List of Controls.
Note that this solution assumes that each carousel panel has at least one CTA (i.e., call to action, or control) in it. Keyboard users simply tab into each CTA as they would any other links on the page. When keyboard users tab into a panel that is offscreen, our JavaScript library ensures that the panel comes into focus. As a result, keyboard access to the previous and next buttons are considered unnecessary, so we have intentionally removed them from the document tabbing order. If you are dealing with a carousel that can have no CTA in one or more panels, you should look at the second carousel example on this page.
The implementation presented here is based on this excellent article by Alison Walden.
Code Walkthrough of the Above Example
Below is the HTML of the above example. Use the dropdown to highlight each of the individual steps that makes the example accessible.
Solution 2: Treat The Carousel Like A List of Content
Like the first example, this carousel example also uses Glider.js, but the previous and next buttons are keyboard accessible; clicking on them applies focus to the carousel panel that slides into view or the first interactive element within the slide if one is available. This is great if you have carousel panels that don't have any interactive elements.
Tab into the previous and next buttons below to cycle the slides in the carousel.
Code Walkthrough of the Above Example
Below is the HTML of the above example. Use the dropdown to highlight each of the individual steps that makes the example accessible.
Installation Instructions
You can load this JavaScript library into your application in serveral ways:
- as an ES6 module using Webpack.
- as a CommonJS module using
require()
and Webpack. - as a native ES6 module within the browser.
- as an old-school ES4/JavaScript library.
If you haven't done so already, choosing which you should use is obviously a major architectural decision. Here are a few articles that will help you decide:
- Jan Olaf Krems gives a great overview of the JavaScript File Format Differences
- Joe Honton discusses that With ES Modules and HTTP/2 You May Not Need Webpack Anymore
- Stack Overflow has a really good thread about Webpack vs ES6 modules as well.
Important Note On The CSS Classes Used In This Module:
This module requires specific CSS class names to be used in order it to work correctly.
These CSS classes begin with enable-carousel__
. Please see the documentation above to see where these CSS classes are inserted.
Using NPM/Webpack to load ES6 Modules:
-
Install the
enable-a11y
NPM project. -
Edit your webpack.config.json file to resolve the
~
modifier by adding the following:module.exports = { ... resolve: { extensions: ['.js', '.jsx', '.scss', '.css', '*.html'], modules: [ path.resolve('./src/js'), path.resolve('./node_modules') ], alias: { '~enable-a11y': path.resolve(__dirname, 'node_modules/enable-a11y') ,'~glider-js': path.resolve(__dirname, 'node_modules/glider-js'), '~glider-js/glider.js': path.resolve(__dirname, 'node_modules/glider-js/glider') }, ... }, ... }
-
You can use the module like this:
// import the JS module import enableCarousel from '~enable-a11y/js/modules/enable-carousel'; // import the CSS for the module import '~enable-a11y/css/enable-carousel'; // Note that this component doesn't currently work when
// new components are added after page load.Note: If you want to have the skip links like in the example above, please ensure you also include the NPM module for skip links as well.
-
Alternatively, if you are using LESS you can include the styles in your project's CSS using:
@import '~enable-a11y/css/enable-carousel';
.css
suffix)
Using NPM/Webpack to Load Modules Using CommonJS Syntax
-
Install the
enable-a11y
NPM project. -
You can import the module using require like this:
var enableCarousel = require('enable-a11y/enable-carousel').default; ... enableCarousel.init();
- You will have to include the CSS as well in your project's CSS using:
@import '~enable-a11y/css/enable-carousel';
Using ES6 modules natively.
This is the method that this page you are reading now loads the scripts.
- Grab the source by either using NPM, grabbing a ZIP file or cloning the enable source code from github.
-
If you want to load the module as a native ES6 module, copy
js/modules/enable-carousel.js
, andcss/enable-carousel.css
from the repo and put them in the appropriate directories in your project (all JS files must be in the same directory). -
Load the CSS in the head of you document:
<html> <head> ... <link rel="stylesheet" href="path-to/css/enable-carousel.css" > ... </head> <body> ... </body> </html>
-
Load your scripts using:
<script type="module"> import enableCarousel from "path-to/enable-carousel.js" enableCarousel.init(); </script>
Using ES4
Just do the same as the ES6 method, except you should get the JavaScript files from thejs/modules/es4
directory instead of the js/modules/
:
<script src="path-to/es4/enable-carousel.js"></script>