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:

  1. Unknown functionality of components
  2. Unknown states and properties of components
  3. Unreported change of dynamic content
  4. Bad keyboard accessibility

Enter WAI-ARIA.

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.

<ul id="myTab" class="nav nav-tabs" role="tablist">
    <li class="active">
        <a href="#home" role="tab" data-toggle="tab">Home</a>
    </li>
    <li>
        <a href="#profile" role="tab" data-toggle="tab">Profile</a>
    </li>
    <li>
        <a href="#articles" role="tab" data-toggle="tab">Articles</a>
    </li>
</ul>

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:

<div id="myTabContent" class="tab-content">
    <div class="tab-pane fade in active" id="home" role="tabpanel">
        <p>Welcome!</p>
    </div>
    <div class="tab-pane fade" id="profile" role="tabpanel">
        <p>My profile.</p>
    </div>
    <div class="tab-pane fade" id="articles" role="tabpanel">
        <p>My articles.</p>
    </div>
</div>

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.

Here is the improved markup for the tab:

<li class="active">
    <a id="tab1" href="#home" role="tab" aria-controls="home" data-toggle="tab">Home</a>
</li>

And here is the new markup for an individual panel:

<div class="tab-pane fade in active" id="home" role="tabpanel" aria-labelledby="tab1">
    <p>Welcome!</p>
</div>

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:

<div id="myTabContent" class="tab-content" aria-live="polite">
    ...
</div>

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.

See the Pen BeplL by SitePoint (@SitePoint) on CodePen.

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.

The following examples are considered bad practice:

<div role="navigation"></div> <!-- don't repurpose, use <nav> instead -->
<h2 role="button"></h2> <!-- don't change semantics, use <button> -->

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:

.button[aria-hidden="true"] {
    display: none;
}

In terms of browser support, you are safe to start using ARIA right now.

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!

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Kate Perry

    Google is paying 80$ per>>CLICK NEXT TAB FOR MORE INFO AND
    HELP

  • Dante

    Nice article. Thank you Stephan…

    • http://stephanmax.is Stephan Max

      Thanks Dante, I’m glad you liked it.

  • prince.gr

    Helpful! Thank you Stephan.