A List Apart

Menu

Accessible Web 2.0 Applications with WAI‑ARIA

Issue № 235

Accessible Web 2.0 Applications with WAI-ARIA

by Published in Application Development, Browsers, Accessibility14 Comments

Web 2.0 applications often have accessibility and usability problems because of the limitations of (X)HTML. The W3C’s standards draft for Accessible Rich Internet Applications (ARIA) addresses those limitations. It provides new ways of communicating meaning, importance, and relationships, and it fills gaps in the (X)HTML specifications and increases usability for all users by enabling navigation models familiar from desktop applications. Best of all, you can start using ARIA right away to enhance the accessibility of your websites.

The extension was first proposed by Richard Schwerdtfeger from IBM, member of the WAI Protocols and Formats Working Group and the HTML Working Group, and Becky Gibson of the WAI WCAG Working Group. Together with Aaron Leventhal they implemented these and other accessibility features in Firefox 1.5-3.0 and various assistive technologies.

All this, of course, is illegal, said Joe Clark about the proposed extension, and while I totally agree that standards should not be broken and that there are more pressing issues to be resolved, the solution was both pragmatic and timely. In August 2005 IBM contributed a vast amount of code to the Mozilla project to enhance accessibility, and shortly after Clark’s critique, the first W3C working drafts for Roles and States and Properties for Accessible Rich Internet Applications (ARIA) were published. Almost a year later, the role attribute was introduced as a XHTML 1.1 module. Remember, the “X” in “XHTML” stands for “extensible”—more on that later. The proposals were pushed through the W3C procedures at unusual speed and are expected to become recommendations in the second quarter of 2007. It’s awesome how efficient the W3C can be under the right circumstances.

Semantic sugar

In today’s web interfaces, menus and breadcrumb navigation are usually built with list items, and the markup includes different sections for a page’s main content and its sidebar. In Web 2.0 applications, anything can be a button or a control interface (a slider, for example). The accessibility problem is that there’s no way for a screen reader to know about the functionality of those elements. The XHTML role attribute fills the gap by adding some semantic sugar:

<ul role="navigation"> […] </ul>

This provides a semantic, machine-readable role attribute that a user agent can map to the OS Accessibility API. The attribute semantically identifies the element and can be read by machines and by those humans who venture into the source code. User agents can map the role to an appropriate platform accessibility API, allowing assistive technologies to interpret the element correctly.

Roles come in two flavors: XHTML and WAIARIA. A basic set is defined in the XHTML 1.1 Role Attribute Module. It is extended by the WAIARIA Role RDF taxonomy. WAIARIA roles have the wairole prefix, like in role="wairole:slider".

Roles are further divided into widgets and structural roles. Widget roles include progressbar, slider, button, tree, textfield, checkbox, alert, and dialog. So if you want to use a fancy layer instead of a system dialog box, you can tell screen readers what it is by using role="dialog". More cool widget examples can be found at mozilla.org.

Custom CSS dialog box on flickr

Common structural roles include main, secondary, group, section, liveregion (in which content is changed by AJAX or some other technique), tab, navigation, menubar, toolbar, breadcrumbs, search, or banner.

Added meaning

The role attribute provides information on what the object is. The States and Properties module (ARIA-State) adds meaning about relationships and current states:

<input type="text" name="email" aaa:required="true" />
<div role="wairole:button" aaa:controls="price"> »
Change sort order</div>
<h2 id="price" aaa:sort="descending">price</h2>

Other states include checked, disabled, expanded, haspopup, invalid, readonly, describedby and labelledby as well as the level of an element in a tree structure, the valuenow, valuemin and valuemax of a slider, and whether or not a menu item is currently the activedescendent.

Where am I?

Assistive technologies need to know what object they are working with and which item has focus. Currently, only links and form elements can have focus. ARIA-State extends common text containing elements with the tabindex attribute, allowing these elements to receive focus either through scripting or via tab navigation.

flickr headline and text input field that is only editable when you click on it with a mouse

For example, currently the only way to give focus to a flickr text input is by clicking on it with a mouse. With tabindex="0", it would become keyboard accessible. Moreover, the tabindex value can be negative. Elements with a negative tabindex can receive focus via scripting, but are excluded from tab order. This feature was introduced by Microsoft in Internet Explorer 5.01 and has been implemented in Firefox from version 1.5 on.

As a reminder, here is a table with the values and behavior of tabindex:

Can get focus Tab navigable
no tabindex default (only form elements and links) default
tabindex="-1" yes no, authors have to program element.focus() in the event of onkeydown for arrow or other keys
tabindex="0" yes yes, in the order as elements appear in the source code
positive, e.g. tabindex="100" yes yes, the tabindex specifies the tab order of elements. These elements get focus before any elements with tabindex="0" or without tabindex.

How to use it

Do we have to wait another ten years until other browsers support these techniques? Actually, no. You can start using roles, states, and properties right away. Currently only Firefox 1.5 or later and three major screen readers (Window Eyes 5.5+, Jaws 7.0+, ZoomText)  support them, but the extra attributes won’t hurt other browsers.

While some of the new attributes are already included in XHTML 2, we have to extend XHTML 1.x. There are three ways to bolt them on:

  1. XML Schema namespaces
  2. DOM Scripting
  3. DTD extension

XML schema namespaces

The most common method to extend XHTML is through namespaces. That’s fairly easy:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:wairole="http://www.w3.org/2005/01/wai-rdf/ »
GUIRoleTaxonomy#"
xmlns:x2="http://www.w3.org/2002/06/xhtml2"
xmlns:aaa="http://www.w3.org/2005/07/aaa">

Firefox 2.0 already recognizes the role attribute, so you don’t need to bring in the role attribute through the XHTML 2 namespace (line 3) for this browser, but you should keep it in for backward compatibility.

Note the misleading historic name for the States and Properties module: here, aaa does not stand for maximum accessibility as defined in the Web Content Accessibility Guidelines, but for “Accessible Adaptable Applications,” later known as “Accessible Rich Internet Applications” (ARIA).

Sadly, the W3C validator throws an error as soon as you start adding namespaces. Why is that? In XHTML 1.0 the xmlns attribute has a fixed datatype and is specified to be http://www.w3.org/1999/xhtml. Period. No exceptions. In XHTML 1.1 it’s supposed to work, but the validator still throws the error.

Advantage: Easy to implement.

Disadvantage: Does not validate as XHTML 1.0.

DOM scripting

HTML 4 does not support namespaces to extend attributes. However, DOM 2 does support namespaces, even in HTML 4, so we can use DOM Scripting to add roles, states, and properties.

In this workaround, role and state information is embedded in the class attribute. IBM has created a well documented JavaScript library to parse the class attribute into namespaced attributes on the element. axs acts as the delimiter, followed by the role and subsequent state-property pairs.

<body>
<div id="slider" class="myslider myselector2 axs slider »
valuemin-0 valuemax-50 valuenow-33" tabindex="0"></div>
<script type="text/javascript" src="enable.js"></script>
<script type="text/javascript">initApp();</script>
</body>

Advantages: Progressive enhancement; the only way to implement roles and states in HTML 4.

Disadvantages: Works only with JavaScript (7.4 KB); each element can be associated only with a single role, not multiple values; supports no other values than those of the WAIARIA Role and ARIA-State taxonomies; the generic function name without object literal notation can cause conflicts with other initApp functions.

DTD extension

We all know XHTML 1.1 is modular and extensible, but only a few über-geeks seem to know how to extend the DTD (fortunately, there are validators for debugging your customized DTD). First you bring in the Role Attribute module, then you extend common elements with the role attribute, and then you bring in the States and Properties module including the XHTML 1.1 driver. See an example DTD.

Implement your customized DTD as usual. You only need to adapt the URI and the your name as the maintainer (“ALA” in the example):

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//ALA//DTD XHTML 1.1 for »
Accessible Adaptable Applications with Role Attribute 1.0//EN" »
"http://learningtheworld.eu/dtd/xhtml-role-state.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

Then we need to bring in the WAIARIA Role taxonomy. If you prefer to avoid namespaces, you can add it with a link element in the head:

<link rel="meta" href="http://www.w3.org/2005/01/wai-rdf/ »
GUIRoleTaxonomy#" type="application/rdf+xml" »
title="WAI‑ARIA Role Taxonomy" />

I don’t want to get into the old MIME type debate, but if you decide to serve the pages with the XHTML MIME type, avoid HTML entities. Browsers like Firefox do not read the DTD. Instead, they parse the DTD URI for known strings, and when they find something they know, you get XHTML in all its glory. Otherwise, it’s just XML. Alas the only named entities known in XML are &lt;, &gt;, &amp;, and &quot;, all other entities throw an error. Use Numeric Character References (NCR) instead, thus &nbsp; becomes &#160; etc. (I use a PHP script for the translation.)

The bundle of ARIA-State with the XHTML driver isn’t a bad idea, but it’s inconsistent with the functionality of all other modules, which come as single entities. It also complicates the implementation of both XHTML-Role and ARIA-State, whereas creating a custom, validating DTD for the role attribute alone is easy. I’m confident these problems will be resolved when the draft becomes a candidate recommendation, as the W3C Protocols and Formats Working Group is very responsive.

Advantages: Validates easily with XHTML-Role; validates with a little tweaking of ARIA-State.

Disadvantages: At the time of this writing, overly complex; only an option with XHTML 1.1.

Conclusion

Whether you start experimenting with the new attributes immediately or wait until the drafts become standards, you have the opportunity to get ready for them now and become an early adopter. So early, in fact, that you are invited to shape the implementation of the extension:

Those types of landmark roles are exposed by Firefox to assistive technologies, and are in the DOM. While currently none of the assistive technologies do anything with those roles, they could. We don’t currently have any plans to do anything with them in Gecko / Firefox, but we’d listen to ideas. If you have a solid idea of what should be done with those roles, please file an RFE (Request For Enhancement) bug under bugzilla.mozilla.org, Product = Core, Component = Disability Access.

Aaron Leventhal (IBM / Mozilla)

Further reading

About the Author

14 Reader Comments

Load Comments