ARIA Switch (a.k.a. Toggle)

A switch (also known as a toggle) is like a checkbox, in that is designed to be an input control that has a binary value (either checked and unchecked or on or off, depending on the screen reader). Like tablists.php, switches do not have a native HTML5 tag, so we implement custom code using the switch role in JavaScript.

Many developers will implement switches using the <input type="checkbox">, since the native HTML5 checkbox control is already accessible. While you could do this, I would argue this is semantically dishonest: partially sighted users who use a screen reader hear that the control is a checkbox, but there is no checkmark involved.

My father, who is partially sighted, has fallen into this trap on a website once on his tablet. He was afraid of submitting an order form because he felt that the screen reader was lying to him, and he was afraid of making a mistake because he didn't know what the control did (he wasn't sure what it was, but it certainly didn't look like a checkbox). He tried to explain to me this issue over the phone, and after quite a few minutes not understanding what the trouble was, I went over to his house to see what he was talking about. After looking at his tablet, I learned a valuable lesson: developers shouldn't be dishonest to users to make things easier for themselves.

A simple switch coded with ARIA.

recommended solution This is the best solution to use, especially when building from scratch.
If you are already using a component similar to this in existing work that is not accessible, go to the developer walkthrough in this section to see how we made our implementation accessible.
This solution described below is available as an NPM module. (Module installation instructions)

This code is based on information from the MDN article on Using the switch role. The switch reports the checked state as "on" or "off" in VoiceOver and "checked" or "unchecked" in NVDA and ChromeVox. In order to make some consistency among user agents, an aria-describedby on the switch can state the "on/off" state to all screen readers. This description is also given visually, to make it obvious what the state is for sighted users. Developers could hide this text with the sr-only class, and put "off" and "on" labels on sides of the right and left sides of the component if they wish instead.

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 make the example accessible.

☜ Scroll to read full source ☞

                    
                

Installation Instructions

You can load this JavaScript library into your application in several ways:

If you haven't done so already, choosing which you should use is a major architectural decision. Here are a few articles that will help you decide:

Using NPM/Webpack to load ES6 Modules:

  1. Install the enable-a11y NPM project.
  2. Edit your webpack.config.json file to resolve the ~ modifier by adding the following:
    ☜ Scroll to read full source ☞
    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') }, ... }, ... }
  3. You can use the module like this:
    ☜ Scroll to read full source ☞
    // import the JS module import switch from '~enable-a11y/js/modules/switch'; // import the CSS for the module import '~enable-a11y/css/switch'; // How to initialize the switch library switch.init(); // Note that this component will work with DOM elements coded like // the examples above added after page load. There is no need to call // an .add() method, like we do with the Enable combobox component.
  4. Alternatively, if you are using LESS you can include the styles in your project's CSS using:
    ☜ Scroll to read full source ☞
    @import '~enable-a11y/css/switch';
    (If you are using it in your CSS, you will have to add the .css suffix)

Using NPM/Webpack to Load Modules Using CommonJS Syntax

  1. Install the enable-a11y NPM project.
  2. You can import the module using require like this:
    ☜ Scroll to read full source ☞
    var switch = require('enable-a11y/switch').default; ... switch.init();
  3. You will have to include the CSS as well in your project's CSS using:
    ☜ Scroll to read full source ☞
    @import '~enable-a11y/css/switch';

Using ES6 modules natively.

This is the method by which the page you are reading now loads the scripts.

  1. Grab the source by either using NPM, grabbing a ZIP file, or cloning the enable source code from GitHub.
  2. If you want to load the module as a native ES6 module, copy js/modules/switch.js , and css/switch.css from the repo and put them in the appropriate directories in your project (all JS files must be in the same directory).
  3. Load the CSS in the head of your document:
    ☜ Scroll to read full source ☞
    <html> <head> ... <link rel="stylesheet" href="path-to/css/switch.css" > ... </head> <body> ... </body> </html>
  4. Load your scripts using the following code (NOTE: you must use <script type="module">):
    ☜ Scroll to read full source ☞
    <script type="module"> import switch from "path-to/switch.js" switch.init(); </script>

Using ES4

Just do the same as the ES6 method, except you should get the JavaScript files from the js/modules/es4 directory instead of the js/modules/:
☜ Scroll to read full source ☞
<script src="path-to/es4/switch.js"></script>