DHTML Developer Checklist
This checklist is intended to provide developers with a quick overview of a few of the most important issues to watch out for when developing DHTML and AJAX-based user interfaces. It may also be suitable as a starting point for thinking about UI technical governance, ensuring all new user interfaces address these issues before being included in a release. Fluid is committed to helping community source developers implement these strategies in their own code, and is working to grow a library of well-designed user interface components that will help to ease the burden of creating accessible, reusable designs.
Developers working on DHTML user interfaces should keep in mind, at the very least, the following techniques:
- Keyboard support: everything that works with the mouse should also be usable with the keyboard.
- Follow ARIA conventions when using the tabindex attribute
- Use consistent and familiar keyboard controls (Tab key, Arrow keys, Enter, and Spacebar)
- Don't use the global namespace
- Avoid overriding built-in types
- Generate unique element ids in your markup
- Label everything: use ARIA to convey UI semantics
Checklist in Detail
1. Keyboard Support: everything that works with the mouse should also be usable with the keyboard
Comprehensive keyboard controls are often overlooked by developers, but are one of the best ways to improve the overall accessibility of your design. A large number of assistive technology users depend on the keyboard to access everything on the web; keyboard accessibility also improves efficiency and convenience for all users.
The basic rule is this: everything that is available with the mouse should also be usable by keyboard. This includes any kind of direct manipulation tasks such as drag and drop, as well as hover effects, tooltips, and similar behaviour.
- The Tab key should provide focus to the widget as a whole. For example, tabbing to the Lightbox puts focus on the overall thumbnail container.
- The arrow keys should allow for selection or navigation within the widget. For example, using the left arrow key in the Lightbox shifts focus to the next image thumbnail.
- When the widget is not inside a form, both the Enter and Spacebar keys should select or activate the control.
- Within a form, the Spacebar should select or activate the control, while the Enter key should submit the form's default action.
- If in doubt, mimic the standard desktop UI behaviour of the control you are creating.
Example Markup Using Tabindex
Here's an example of how you would use the tabindex attribute for a typical menubar interface:
* The menu bar itself will be focussable with the Tab key.
* Notice that I have to explicitly set the tabindex of focussable items such as <a> tags to "-1" to assure they aren't available in the tab order.
<li id="menubar" tabindex="0">
<li><a href="/open" tabindex="-1">Open File...</a></</li>
<li><a href="/save" tabindex="-1">Save As...</a></li>
<li><a href="/print" tabindex="-1">Print...</a></li>
<li><a href="/cut" tabindex="-1">Cut</a></li>
<li><a href="/copy" tabindex="-1">Copy</a></li>
<li><a href="/paste" tabindex="-1">Paste</a></li>
For more detailed information about keyboard navigation, check out the Mozilla Developer Center's Key-navigable custom DHTML widgets article.
To test your browser's handling of the tabindex attribute, consult the Tabindex Focus Navigation Tests article.
Here are some techniques to make your code more portal-friendly:
- Namespace everything: don't use the global namespace
- Don't override the behaviour of built-in types such as Object or Array
- Generate fully unique element IDs for your markup
Multiple Placements: Another complication is the issue of multiple placements of the same portlet. In a portal, more than one instance of a portlet can appear on a single page. This requires all markup to be unique to each instance of the portlet such that there won't be conflicts or ambiguity when manipulating DOM elements by id. In other words, ensure that your generated markup includes a unique prefix for all element ids. This additional level of markup namespacing can be provided by tools such as the Portlet taglibs for JSP, or the built-in functionality of a portlet-friendly presentation framework such as RSF.
The biggest accessibility problem with DHTML is a lack of semantics. Most Web 2.0-style user interfaces bring richer controls similar to those found on the desktop. The problem is that HTML doesn't provide enough built-in information to properly describe these types of controls to users of assistive technology.
Current assistive technology is well-equipped to work with common UI controls found on the desktop. Indeed, the fact that many DHTML widgets more closey mimic their desktop counterparts provides the opportunity to make the web much more accessible and familiar than it has previously been. The challenge is ensuring that the assistive technology knows enough about the meaning of the markup to correctly represent these controls. In other words, we need to add additional information to the markup in order to ensure that assistive technologies understand the characteristics and behaviour of our DHTML user interfaces.
The Problem of Insufficient Semantics
At the core of the DHTML accessibility problem is a lack of UI semantics; HTML doesn't give us enough richness to properly describe user interfaces to assistive devices. DHTML controls are often built using generic grouping elements such as
<span>, or by overloading existing types such as lists. These tags don't provide us with any further indication of what the control does, or what properties and states it possesses. So imagine a tab-based navigation bar in a web application. The markup might look something like this:
While the markup may look and feel like a group of tabs visually, we have no explicit labels or semantics to communicate this behaviour to the browser and assistive technology.
Using ARIA to Add Semantics
ARIA's goal is to fill in the semantic gap missing from HTML. Created by the W3C, ARIA is a specification describing additional markup for Accessible Rich Internet Applications. It allows you to add specific attributes to your XHTML elements in order to help specify the roles, properties, and states of a particular interface control. Roles describe the type of user interface control, for example: menus, tabs, sliders, grids, trees, and tool tips. States and properties describe the various modes or settings a control can have, for example: disabled, selected, busy, readonly, etc.
Using ARIA, our tab example above would look like this:
<ul id="tabNavigation" role="tablist">
<li class="tab" role="tab">Home</li>
<li class="tab" role="tab">Books</li>
<li class="tab" role="tab">Music</li>
<li class="tab" role="tab">DVD</li>
The contents of the tab panel go here.
The addition of the namespaced ARIA roles for tabs, tablists, and tabpanels will be sufficient to convey the meaning of the interface to users of assistive technology, ultimately making this interface far clearer and more accessible to all users.
While ARIA takes a bit of work to understand, it is fundamentally required to make DHTML user interfaces accessible to a broad range of users. The added benefit is that ARIA provides further semantic richness to your markup that can be used for CSS selectors, DOM manipulation, and so on.