Magento has accessibility problems. I’ve worked on several Magento projects by now and I’ve tried to do little things here and there to make it more sane, like using more semantic elements (
The (much improved) responsive theme that shipped with Magento CE 1.9 / EE 1.14 includes the very useful
toggleSingle() jQuery plugin for toggling stuff. It looks like this:
(Magento uses $j for jQuery)
I like this. While working on MarcEcko.com, I decided to make a few small changes to it that make it a bit more accessible. The ARIA spec provides a few properties that are useful for us here, namely:
We can look at Heydon’s Practical ARIA examples (from his book, which I highly recommend) to see how we can use ARIA to make our toggled content more accessible.
From his example:
Notice that, even without the ARIA attributes, his toggle is more semantic than the code example from Magento: the toggle is a
button element, inside a heading. Much better than a
div. The code example from Magento uses
<div class="block-title">. A
div carries no semantic value. Although the word title is in there, it doesn’t mean anything to machines like search engine crawlers and screen readers. There’s also no indication that the block title is actionable.
aria-controls attribute on Heydon’s heading button communicates that the button controls some other element, and potentially gives the user a shortcut to jump directly to the element it controls. Like all ARIA attributes that identify elements,
aria-controls uses ID.
aria-expanded tells us the state of the button, announced by screen readers as something like “button collapsed.”
aria-hidden on the content tells us whether it’s visible or not.
Once I activate the button to show the content, this is what I should see in the DOM:
Only two things have changed:
aria-hidden. These attributes semantically communicate the state of our little component, and I can use them in my CSS to visually show and hide it:
All of this comes from Heydon, and it’s wonderful. Let’s contrast it with the way
toggleSingle() works. Here’s the relevant portion:
toggleSingle() relies on classes to show/hide stuff. When the script is executed, the content gets a
.no-display class which sets it to
display: none. I think there’s even an
!important in there. When you click the title, the class is toggled. Simple enough.
Let’s add the ARIA attributes. Starting with the click event:
This takes care of
To put it all together, here’s our improved accessible take on
I added a couple of things here: - Initializing the ARIA attributes on the button - Switching focus to the content once expanded - Removing the attributes when the destruct option is passed (except for the ID).
I recently rewrote a slightly better version of this plugin. It optionally allows you to toggle some arbitrary content rather than just the next element, and it wraps the inside of the toggle in a
<button> tag, if it isn’t one already, for better semantics. Check it out here on GitHub.