Twitter Vimeo download Facebook Pinterest flash Brackets { }

Introducing A11y Toggle

If you’re only here for the code, go straight to the GitHub repository.

A few weeks ago, I introduced a11y-dialog. Today, I am coming back with another accessibility-focused module: a11y-toggle.

At Edenspiekermann, we used to heavily rely on the checkbox hack to toggle content visibility. Unfortunately, this hack (the word is an understatement) involves some usability and accessibility concerns.

What’s wrong with the checkbox hack?

For starters, the checkbox hack relies on the :checked pseudo-class which is unfortunately not supported everywhere (source QuirksMode). In case you’re too lazy to check the compatibility tables, here is a list of browsers not supporting :checked:

That’s a lot of people excluded just for the sake of simplicity (which is also arguable). On top of that, the checkbox hack has some accessibility issues. See, for a content toggle to be fully accessible to assistive technology users, it should respect the following:

All of this cannot be done with CSS itself. Initial ARIA-specific attributes can be set, but they cannot be updated on toggle use, which makes the whole thing quite broken.

JavaScript to the rescue!

So we need JavaScript (unfortunately). However, we don’t need a hell lot of it. A few lines are enough. And that’s precisely what a11y-toggle does (in roughly 300 bytes once gzipped). It just makes it work™.

You can install it through npm:

npm install --save a11y-toggle

Include the script in your app / pages and you should be good to go. You only have to add a data-a11y-toggle attribute linking to the collapsible element’s id. For instance:

<button data-a11y-toggle="content-container">Toggle content</button>

<div id="content-container">
  Here is some content that can be be toggled visible or invisible.

a11y-toggle is adding the initial aria-hidden, aria-controls and aria-expanded attributes so you don’t have to worry about them.

What’s next?

I would like to investigate on the <details> and <summary> elements as they are basically a native implementation for content toggles. Given the poor browser support, I could consider making a11y-dialog a polyfill for these.

Anyway, if you have any idea to make it better or if you found a bug, please reach out to me on Twitter or open an issue on GitHub.

Hugo Giraudel’s avatar

Hugo Giraudel is a CSS goblin, Sass hacker, and serial writer who used to work at Edenspiekermann (Berlin) as a front-end developer.