Category: accessibility

WAI-ARIA: the dark art of accessibility?

When I’m auditing sites for accessibility issues, I find that WAI-ARIA has been used in an attempt to improve the accessibility of the content. And that’s exactly why WAI-ARIA exists, but so many implementations misunderstand how the tools provided by WAI-ARIA should work together.

A few weeks back I was interviewed on the A11y Rules podcast by Nic Steenhout. In it, I discuss what I believe to be the biggest barrier to a more accessible World Wide Web, which I believe to be awareness. In my experience, it’s not that there is a lack of willingness by web developers to incorporate accessibility, but rather that there is much confusion and misunderstanding of how accessibility technically works and what is expected of web developers. And at an organisational level, there is often a commitment to accessibility, but little culture of accessibility throughout various teams that each have a role to play in creating accessible digital products.

I end the interview with Nic by saying that accessibility is not a dark art. That said, one area of accessibility that often stumps even the most experienced developers, is WAI-ARIA – the Accessible Rich Internet Applications (ARIA) specification.

So, combining these two thoughts together, this is an awareness-raising blog post for web developers about ARIA. It was prompted by an issue discovered on a client’s website that was using a carousel powered by Slick. I’m going to take a look at some of the ARIA used by Slick.

In summary (tl;dr)

One of Slick’s demos includes the following code hierarchy:

<div role="toolbar">
  <ul role="tablist">
    <li role="presentation" aria-selected="true" aria-controls="[invalid id]">
      <button role="button" tabindex="0">

In summary, the issues are:

  1. ARIA toolbar and tablist roles are mixed together.
  2. The tablist contains no elements with tab roles.
  3. The aria-selected state and aria-controls attributes are applied to inappropriate elements.
  4. aria-controls attributes reference element IDs that do not exist in the page.
  5. The <button> element’s role is duplicated by role="button".
  6. The tabindex="0" applied to the <button> is unnecessary.

What is WAI-ARIA?

The Accessible Rich Internet Applications specification is maintained by the WAI at the W3C. It provides a toolkit of attributes that allow us to enhance the native roles of HTML elements to build more accessible user experiences.

These days, HTML alone does not provide enough of a toolkit to build a desktop-like experience on the Web, so we build custom controls using lots of JavaScript. This is great, but to do so in an accessible manner, we need some additional tools to fill in the gaps in HTML’s teeth.

What’s your beef with Slick, huh?

Before I get started, I don’t mean to pick on Slick here, but it struck me as a good example of where even expert JavaScript developers can build for accessibility and still get things wrong.

The accessibility community doesn’t much like carousels as they embody several accessibility and usability issues, even when the individual components that make up a carousel are made technically accessible. This has resulted in resources like being born, demonstrating some of the issues.

Slick’s demos have obviously been built with accessibility in mind, which is great. However, some basic misunderstandings have resulted in some poor ARIA implementations.

Examining the code

In the interests of time and clarity, I’m not going to take you through every issue with Slick’s demos, but rather look at one part of the interface: the navigation dots for the carousel in the “Single Item” demo.

The navigation dots for Slick’s demo carousels are implemented as a tab list. We can extract the following DOM hierarchy from the HTML used:

<div role="toolbar">
  <ul role="tablist">
    <li role="presentation" aria-selected="true" aria-controls="[invalid id]">
      <button role="button" tabindex="0">

What are the problems here? Let’s examine this code snippet and try out Slick’s “Single Item” demo using NVDA screen reader.

Avoid mixing incompatible ARIA roles

The first two elements in the hierarchy represent a toolbar with a tab list nested inside it. These ARIA attributes are described in the specification as follows:

  • The ARIA toolbar role represents a collection of commonly used function buttons or controls represented in compact visual form.
  • The ARIA tablist role represents a set of tab elements.

It really doesn’t make sense to have a tablist role nested inside of a toolbar role. Using the toolbar role to contain the previous and next buttons that control a carousel is fine, but it should not mix with the semantics of a set of tabs.

ARIA interfaces should be self-contained and should not mix incompatible roles together.

Note: Technically speaking, toolbar implies a grouping structure role and tablist is composite widget role. A grouping role is permitted to wrap a widget, but that does not mean that it makes sense to do so – valid does not equal semantically appropriate.

Using ARIA roles is a promise

With great power comes great responsibility. Don’t misjudge ARIA – it is powerful. But using the semantics that ARIA provides is not the end of the story. Adding ARIA roles to your HTML is a promise to code in any expected roles, states and properties for that role, as well as to implement the expected behaviours using JavaScript.

The navigation dots are implemented as a set of tabs, which would make sense for a carousel where only a single item is displayed at any one time. Any element with a tablist role should contain elements with role="tab" that reference elements that have role="tabpanel". There are no tab controls. There are no tab panels. It’s a tab list containing buttons, which is functional but not expected.

Slick’s toolbar does not implement the best practice focus management for toolbars to provide the expected keyboard behaviours (using a roving tabindex implementation).

Discrete DOM nodes are responsible for communicating accessibility information

Accessibility information coded in your HTML is conveyed by browsers to assistive technology via accessibility APIs. These APIs convey graphical user interfaces as a hierarchical tree of accessibility information similar to – but not the same as – the DOM.

For each part of an ARIA-based widget, discrete nodes in the Document Object Model (DOM) are responsible for communicating accessibility information to assistive technology. For most controls and widgets, ARIA state and property attributes relevant to a particular role need to be applied to a single HTML element that is responsible for carrying accessibility information. When multiple HTML elements need to work together to form a widget, most of the time this needs to be achieved using programmatic relationships, such as aria-describedby, aria-controls, etc.

In our accessibility testing, we often see ARIA attributes related to a particular component strewn across multiple HTML elements. This is akin to putting the required attributes of an HTML <input> element somewhere other than on that <input> element. That just doesn’t make sense, right?

Taking a look at our code snippet from Slick, we can see an ARIA state (aria-selected) and an ARIA property (aria-controls) are both separated from the element to which the attributes are related. The list item to which these ARIA attributes are applied is marked as presentational, which essentially makes it semantically the same as a <div>. This is not an appropriate location to apply these attributes.

Note: Despite the role="presentation", NVDA announces the buttons as “bullet 1 button”, “bullet 2 button”, etc.

There is a set of aria-selected attributes on the navigation dots that toggle correctly as each slide of the carousel becomes visible. However, these attributes are incorrectly applied to the containing <li> element rather than the control itself. As a result, NVDA ignores the aria-selected attributes and does not announce which of the slides is currently active. The aria-selected attribute must always be added to an element that has a role. A selected <div> makes no sense. On the other hand, a selected tab does make sense.

Note: The aria-current attribute should not be used as a substitute for aria-selected on a set of tabs.

An aria-controls attribute is primarily intended for creating a programmatic relationship between a control and the element on the page that is controlled by it. For example, a tab controls a tab panel. As with the aria-selected attributes, the aria-controls attributes in the Slick code are incorrectly applied to the containing <li> element rather than the control itself. These attributes also reference element IDs that do not exist in the page.

Avoid duplicating HTML semantics with unnecessary ARIA attributes

The <button> element in the snippet of code we’re looking at includes two unnecessary ARIA declarations: role="button" and tabindex="0".

This breaks the first rule of ARIA use – use native HTML elements whenever possible – and provides no additional benefit by being applied to the button.


HTML’s <button> element has an implicit accessibility role of button, so there is no need to duplicate this using the role attribute.

HTML <button> elements are natively keyboard focusable. Applying tabindex="0" to an element causes that element to become keyboard focusable and part of the natural focus order of the page. The only reason we may see this is if the ARIA role being used expects a single tab stop, which is implemented by using a roving tabindex. This is the expected behaviour for a set of tabs, for example, so the tabindex attribute would actually belong in this code if it was implemented correctly as a set of tabs. However, examining the behaviour in the demo, the buttons used for the navigation dots all have tabindex="0" applied and never change to tabindex="-1".

Other issues

The seasoned accessibility experts reading this may notice other issues that exist with Slick’s demos, which include:

  • An aria-live region is used to wrap the content of the carousel slides, which causes NVDA to announce the content of every carousel in some circumstances (compare NVDA running with Chrome versus Firefox).
  • Listbox widgets and role="option" attributes are used to mark up each slide, which is a misunderstood implementation of the specification, which is intended to extend HTML’s native <select> elements.
  • The aria-label attributes applied to the previous and next buttons are unnecessary as they duplicate the text content inside the <button> element that already acts to provide an accessible name.
  • Poor visibility of keyboard focus.

Aside from the issues with ARIA semantics discussed above, Slick is described as being “fully accessible with arrow key navigation”. The expected method of operating many ARIA interfaces from the keyboard is to use your keyboard’s arrow keys. However, Slick’s demo carousels do not respond to presses of the arrow keys on a keyboard.

Something I mentioned in the podcast interview with Nic is that I don’t believe there is such as thing as “fully accessible”, so I try to avoid using that phrase. It’s no easy task making something accessible to every person and accommodate the way they interact with the world. You can only do your best to make things as accessible as you can.

So, um… not a dark art, huh?

I’ve covered quite a lot in this post by only looking at a small snippet of code. This may seem daunting to many web developers reading this, but ARIA really isn’t as hard as it may seem. I hope you feel like you now understand a bit more about ARIA and how to use it appropriately.

As with any aspect of coding, it’s important to understand your tools before you use them. In the case of ARIA, my advice is:

  1. Read me first because no ARIA is better than bad ARIA.
  2. Familiarise yourself with the rules for ARIA use in Notes on ARIA Use in HTML.
  3. Practice your art forms, even the dark ones.


Thanks to Steve Faulkner for helping clarify a point about ARIA semantics… and also for turning my own confusion around ARIA into understanding many years ago.

Originally published on Updated in May 2022 to link to the new ARIA Authoring Practices Guide.

A11y Rules podcast interview

The A11y Rules podcast presents a series of conversations between people involved in web accessibility and the host, Nic Steenhout.

I’ve known Nic for a long time, so it was great to chat with him about my journey to a career in accessibility, from growing up in a guest house in Devon, through a degree in Electronic Engineering, music technology, working with Drake Music, starting my own web development business, moderating Accessify Forum (now defunct) and learning from people like Steve Faulkner, Patrick Lauke, Gez Lemon, Tommy Olsson et al, through to cofounding Dig Inclusion.

I hope you enjoy listening.

A11y Rules podcast, episode 25 – Interview with Jon Gibbins, part 1

The first part of the interview, where we discuss how I got started in web accessibility and how I connect with disability, the work I currently do, how organisations can use build a culture of accessibility in their teams, and the cost of accessibility. There’s a full transcript of part 1 on the podcast website.

A11y Rules podcast, episode 26 – Interview with Jon Gibbins, part 2

The second and final part of the interview, that centres around discussing lack of awareness around accessibility, and the misunderstandings and misconceptions that arise from poor understanding of people with disabilities and the technologies they use to interact with the digital world. There’s a full transcript of part 2 on the podcast website.

Scripting Enabled debrief

I spent a great weekend up in London at the Scripting Enabled conference and hack day. It was really great to catch up with people I haven’t seen in a while and to meet new people as well. There were a couple of “click” moments like bumping into Peter Abrahams while scanning through the alphabetically-challenged name tags and then figuring out that the lovely lady from Devon was Laura Whitehead who had recently blogged about my list of accessibility videos!

The Scripting Enabled difference


I come away from web conferences and geek meets inspired and chomping at the bit to get working on some of the ideas that have come out of such events. I get back to my cave, start blogging about something that I need to get out there, get distracted by something I wanted to look up (“Right, let’s open that in another tab and deal with it later”), rarely properly finish the entry, get back to doing proper work and not find the time to work on that cool idea or at least put the idea out there. Well, no more, damn it!

What has been the difference at Scripting Enabled this week? The hack day which followed the day of talks and discussion made sure I took the time out to do something with an idea.

Doing the hack day straight after the talks meant things were fresh in our minds and a lot of the clever people who were at the conference were on hand for the day of hacking to work with on an idea and to bounce ideas off of. Having people in the same room with different abilities and disabilities really made the hack day a hive of activity.

On top of that, the event was free to attend. Christian did a fantastic job of pulling together the sponsorship, venues, speakers, hackers… There are lots of people who have given to this event to bring together great people to produce results. I can’t wait for the next one now!

What did I do? I worked in a group of beautiful people to improve accessibility of maps on the Web using the Google Maps API. We were so chuffed to have something to show at the end of the day, but we’re not quite ready to show the world yet. Expect more words from me on that.

In the meantime, check out the photos from the event and keep an eye on the Scripting Enabled site.

Help save the Accessibility Institute

Most people with an interest in web accessibility are likely to have at some point stumbled across the work of the Accessibility Institute at the University of Texas in Austin, which was founded by the late Dr. John Slatin.

The University of Texas has decided to close the Accessibility Institute, which has been a guiding light in our field, giving important opportunity for research and providing useful resources to the world. It would be a real blow to web accessibility to see it go.

If you care about web accessibility, please show your support by putting your name on the petition to save the Accessibility Institute that Knowbility have set up. It only takes a few seconds to do.

There are some great thoughts and comments from people who have signed the petition. Henny Swan has also given some reasons to keep the Institute going on her blog:

Reasons for saving the Accessibility Institute include:

  • Need for research based findings to support accessible design practice.
  • Opportunity for a world class institution like UT to serve as an example to other institutions.
  • Place where emerging practices can be tested and modelled.
  • Contributions to international body of knowledge on inclusion.
  • Maintain thought leadership in Texas, easily disseminated to state agencies that have accessibility mandates.

Thanks for taking the time to read this. Extra special thanks if you have signed the petition.

Read more

John Slatin Fund Accessibility Project

John Slatin was a leading light in the field of web accessibility, which is a passion of mine and my area of work. He co-authored Maximum Accessibility – a book on web accessibility – was co-chair of the WCAG Working Group for a time and led accessibility research at the University of Texas at Austin. Sadly, John passed away in March after a three-year battle with leukaemia.

I never met John, but along with many other accessibility experts, I’m taking part in the John Slatin Fund Accessibility Project to help raise money for John’s wife, Anna, to honour John and to promote his cause; accessibility.

The project aims to raise money to help his family with the medical expenses incurred during John’s illness. Volunteer accessibility experts are matched to companies that want to have their web site checked over for accessibility issues. In return for a brief accessibility audit, the web site owners contribute a minimum of $500 to the John Slatin Fund.

More than 70 accessibility experts have volunteered their time to the project; now we’re looking for companies to take part too. If you work for or know of a company that would be interested in taking part, please point the appropriate people to the project information for companies or contact me directly.