An Introduction to WAI-ARIA

It might come as a shock, but I tell you: The web has changed! The last eight years have seen the rise of Ajax, JavaScript, HTML5, and countless front-end frameworks. Consequently, the internet is no longer a place of static HTML pages, as funny as they sometimes are. Rather, it has become a playground for complex, almost desktop-like web applications, each with their own widgets, controls, and behavior.

Most of us take this for granted and push web development to the limit. However, there is also a non-negligible number of people with disabilities who still struggle with these new techniques. This is not due to disabled JavaScript or insufficient capabilities of current assistive technology (AT). On the contrary, in 2012 WebAIM found that over 98 percent of screen reader users had JavaScript enabled. Additionally, ATs like screen readers or refreshable Braille displays are getting better every year.

The problem lies with HTML’s limited ability to mark up web applications that make heavy use of JavaScript and produce a huge amount of dynamic content. Four key obstacles can be identified when ATs deal with JavaScript applications:

WAI-what?

ARIA, as it is sometimes referred to, stands for Accessible Rich Internet Applications. It is a technology specification that was designed by the Web Accessibility Initiative (the WAI part that completes the acronym) in the W3C (the World Wide Web Consortium) and it is now a W3C recommendation.

You could think of ARIA as a suite of attributes to be included in your usual HTML code. These additional semantics help ATs to identify properties, relationships, and states in your user interfaces. That way ARIA tackles the accessibility challenges mentioned above and allows developers to make advanced web applications more usable for people with disabilities.

Let us now take a look at Bootstrap’s tab panel widget and explore in detail how ARIA helps us augment the given HTML structure to make it more accessible. We will address each of the aforementioned key problems along the way.

1. Functionality via Roles

ARIA provides a rich role taxonomy that enables you as a developer to classify otherwise meaningless tags. That prepares the tags for ATs by revealing the functionality or the part they play in the overall web document.

Bootstrap uses an unordered list to mark up its tabbed navigation. The framework also uses the ARIA roles tablist and tab correctly.

Those roles override the usual list and list element type and expose this HTML snippet to represent a tab list. We should take this one step further than Bootstrap. Here’s the HTML for the panels, within which we’ll add the correct ARIA roles:

Note: Please ignore class names like active and tab-pane; they belong to Bootstrap and are for presentational purposes only.

Roles help set a solid foundation, but that is not the whole story.

2. States and Properties

ARIA states and properties offer the user further information on how to interact with a particular widget. This is all about revealing the relationships and states of our application to users on keyboards and screen readers. Mercifully, the W3C provides us some detailed WAI-ARIA best practices to follow.

So far, we have a tab list and a number of panels. However, the connection between them only exists because Bootstrap’s JavaScript ties them together. In other words, there is no inherent relationship. ARIA comes to the rescue with the aria-controls and aria-labelledby properties.

The aria-controls property is used to associate a control with the region it controls. The aria-labelledby property is used to indicate the element that works as a label for the element.

Note how these elements are connected by using the value of the respective id attributes.

What else should we describe explicitly? We could say that at any moment in time, only one tab is selected and only the corresponding panel is visible. Fortunately, aria-selected and aria-hidden are here to save the day! They are Boolean and can be set to true or false. These can be changed using JavaScript on the appropriate tabs and defaults can be set in the markup to begin with.

3. Live Regions for Dynamic Content

Discovering dynamically updated content without page reload is one of the biggest obstacles for screen readers, especially in the days of Ajax, Node, and single-page applications. How should these be handled? Should the whole page be spoken again? Or should the AT do nothing, risking that the user will miss important updates?

Even something as simple as our little tab list can be tricky. Imagine we use a timer function to loop through our tabbed interface (similar to an image slider). This will lead to different content displaying depending on the currently selected tab.

To fill this gap, ARIA established the concept of live regions that allow ATs to be notified whenever there are changes in that particular part of the document.

Let’s implement a live region in the div that contains the currently visible tab panel:

Setting the aria-live property to polite means the screen reader will wait to announce the change only when the user is not busy doing another task on the page. A value of assertive would notify the user immediately.

4. Enhanced Keyboard Navigation

In the old days of HTML4, the only elements that could receive keyboard focus with the TAB key were links and form elements. This had some serious implications for people who were forced to operate a web page without a mouse. How are they supposed to navigate to span or div elements that might pose as tabs or drop-down menus?

As a result, ARIA enabled every HTML element to receive keyboard focus by extending the tabindex attribute. Today, this is part of the HTML5 specification.

Adding some JavaScript concludes our example and makes Bootstrap’s tab panel widget keyboard-accessible. Check out the CodePen demo and try to operate the widget with the TAB and arrow keys only.

Note: You can use a negative number as a tabindex value. Elements with a negative tabindex cannot be reached with the TAB key but only with JavaScript. This comes in handy when you want to reveal functionality as the user progresses through your application.

Make sure to read the section on Keyboard Navigation on the Mozilla Developer Network for more best practices.

ARIA and HTML5

HTML5 (also called the living HTML standard) has added several useful, semantic tags, and attributes to the language, e.g. the progress and nav element, and the required attribute. Nowadays it is not always recommended to add ARIA code when HTML has you covered.

If there is a suitable HTML element or attribute already implemented, but the accessibility support is not yet available, it is of course allowed and encouraged to use ARIA.

There are still a lot of situations where ARIA proves useful. Do not miss the opportunity to read accessibility mastermind Steve Faulkner’s thoughts on that topic — more than 4 years old, still valid!

Can I use ARIA without Risk?

Absolutely! ARIA was designed to be recognized only by assistive technology and does not affect the DOM or your styling in any way. This does not mean, however, that you cannot leverage ARIA roles and properties with CSS to style your application accordingly:

Conclusion

ARIA was designed to be supportive while being easy to implement. It won’t restrict your workflow in any way, instead providing you a set of roles, attributes, and semantics to build feature-rich yet accessible web sites.

In case you need a little more convincing, try this screen reader simulation and experience how it feels to be dependent on your assistive technology and thus on properly implemented web applications. We as responsible developers have to step in and pave the way!

Stephan is a Germany-based computer science graduate and front-end developer with a soft spot for back-end technologies. He distrusts people who think JavaScript is not a real programming language, adores people who cherish clean design and concise code as much as he does and greets his co-founder folks over at deepr journalism. His superpower is transforming energy drinks into code.