It is important that all users can access applications built using Dojo. People with disabilities access the Web in many manners. Some people rely on the keyboard only to navigate and make selections. Others use custom font and color settings, custom style sheets, screen magnification or screen readers to interact with the computer. With the addition of multimedia to the Web, captioning is important for folks with hearing loss. Those with cognitive disabilities may use a variety of assistive technology to adapt the content to a particular learning style.
In addition, many countries require that Web content is accessible to all. Section 508 of the Disabilities Act requires the US Government to purchase accessible technology. Australia, Japan, Great Britain and the European Union all have accessibility regulations. Thus, it is important for the Dojo Toolkit to provide a way to build accessible applications.
<div/> and /* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */
.html4strict .imp {font-weight: bold; color: red;}
.html4strict .kw1 {color: #b1b100;}
.html4strict .kw2 {color: #000000; font-weight: bold;}
.html4strict .kw3 {color: #000066;}
.html4strict .coMULTI {color: #808080; font-style: italic;}
.html4strict .es0 {color: #000099; font-weight: bold;}
.html4strict .br0 {color: #66cc66;}
.html4strict .st0 {color: #ff0000;}
.html4strict .nu0 {color: #cc66cc;}
.html4strict .sc0 {color: #00bbdd;}
.html4strict .sc1 {color: #ddbb00;}
.html4strict .sc2 {color: #009900;}
<span/>, the assistive technology needs additional information about the created component and its behaviors.
The W3C Web Accessibility Initiative Accessible Rich Internet Applications (WAI-ARIA) Roadmap provides specifications that describe how to provide this additional information to the assistive technology. These specifications define a set of roles and states that can be added to the created DHTML user interface components. With the addition of this information and support by the browser and assistive technology, a user of AT can obtain detailed information about the user interface components created for the Web. For example, a tree component is identified as a tree and each tree item, its level in the tree, expanded and collapsed state and number of children is now available to a screen reader user. The current ARIA specifications are supported in Firefox 1.5 and later versions as well as the by the Window-Eyes screen reader beginning in version 5.5 and partial support by JAWS beginning in version 7.1. Support from other Windows browsers and assistive technology vendors are expected in the future. To provide the most comprehensive accessibility solution for Dojo, the ARIA techniques are being applied to the dijit widgets.
Customizing the dijit Widgets look and feel is very important, as is performance. The Dojo team uses background images in the creation of the widgets because it allows the look and feel of the widgets to be easily customized by modifying the CSS. In addition, using CSS allows several images to be combined into one file and then the proper subset of the image to displayed using positioning. Thus all of the images for a particular widget element can be retrieved via one HTTP request rather than a separate request for each separate image file. For these reasons, Dojo did not want to require the use of image elements when creating widgets. This presents a problem for users with high contrast mode settings because in this mode, background images are not displayed.
This problem is solved in dijit by checking for high-contrast mode when the widgets get loaded. If high-contrast mode is detected, an additional style sheet is added to the body element of the page. This is NOT a style sheet to provide a set of high-contrast mode colors and styles – it is an enhancement to the existing style sheet to enable text equivalents for the items that rely on CSS images.
For example, in the default Dojo theme called tundra, the close icon for a dialog box is represented using a CSS background image of an x within a shaded circle which is displayed in the upper right hand corner of the dialog box.

Within the dialog template there is an additional span that contains the character ‘x’ to serve as the text alternative for the background image icon.
/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #b1b100;} .geshifilter .kw2 {color: #000000; font-weight: bold;} .geshifilter .kw3 {color: #000066;} .geshifilter .coMULTI {color: #808080; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #ff0000;} .geshifilter .nu0 {color: #cc66cc;} .geshifilter .sc0 {color: #00bbdd;} .geshifilter .sc1 {color: #ddbb00;} .geshifilter .sc2 {color: #009900;}This span has a style of .closeText which is defined as follows:
/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #000000; font-weight: bold;} .geshifilter .kw2 {color: #993333;} .geshifilter .co1 {color: #a1a100;} .geshifilter .coMULTI {color: #808080; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #ff0000;} .geshifilter .nu0 {color: #933;} .geshifilter .re0 {color: #cc00cc;} .geshifilter .re1 {color: #6666ff;} .geshifilter .re2 {color: #3333ff;} .geshifilter .re3 {color: #933;} .geshifilter .re4 {color: #933;}Notice that the closeText style is encapsulated within .dijitDialog so this style applies when it is cascaded within an element which has the .dijitDialog style applied. The span with .closeText applied is set to display:none. The dijit.css style sheet contains an additional style:
/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #000000; font-weight: bold;} .geshifilter .kw2 {color: #993333;} .geshifilter .co1 {color: #a1a100;} .geshifilter .coMULTI {color: #808080; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #ff0000;} .geshifilter .nu0 {color: #933;} .geshifilter .re0 {color: #cc00cc;} .geshifilter .re1 {color: #6666ff;} .geshifilter .re2 {color: #3333ff;} .geshifilter .re3 {color: #933;} .geshifilter .re4 {color: #933;}When high-contrast mode is detected the .dijit_a11y class is applied to the body element of the page and now the span with class .closeText is made visible via the display:inline directive. In high-contrast mode, the background image of the close icon is no longer visible but the character ‘x’ is displayed.

In some cases, an HTML entity character such as, ▼ - the Unicode black down pointing triangle (▼) is used as the text alternative. This character is used to provide the down arrow character to indicate a popup is available. This provides some issues for screen readers that may not correctly speak the HTML entity character, but the ARIA describedby and labelledby attributes are used to provide the correct text description for the character when necessary.
The high contrast detection code is in dijit._base.wai.js in the onload function. This function is run before the widgets are created to detect if a Windows system running Internet Explorer or Firefox is in high contrast mode. This function can also detect if images are turned off in Firefox when running via http (images are not turned off in Firefox when running from the file system even if Tools Options Content Load images automatically has been unchecked).
The high contrast detection code uses scripting to create an element, set specified style attributes on the element and append it to the body element. The styles assigned are two different border colors to the top and side borders, a background image, and absolute positioning to render it off screen. Next the computed style for the element is obtained and the border colors are compared. If high contrast mode is turned on, the top and right border colors will both be the same color since high contrast mode overrides CSS specified colors for the high contrast theme color.
Image detection works by examining the background image for the element. If images are turned off the background image style will “none” in IE or “url(invalid-url:)” in Firefox. Note however, that image off is only detected in IE when it is already in high contrast mode. Additional work is underway to determine images off mode in Internet Explorer in all cases.
One of the keys to supporting the keyboard is to allow focus to be set to any element. The tabindex attribute can be used to include additional elements in the tab order and to set programmatic focus to them. This was a feature implemented in Internet Explorer that has been extended to Firefox and Mozilla. The following table outlines the use of the tabindex attribute:
| Tabindex Attribute Value | Focusable via mouse or scripting via element.focus() | Tab Navigation |
| not present | Follow default behavior of element (only form controls and anchors receive focus) | Follows default behavior of element |
| zero - tabindex="0" | Yes | In tab order relative to element's position in document |
| positive - tabindex="x" (where x is a positive integer between 1 and 32768) | Yes | tabindex value directly specifies where this element is positioned in the tab order |
| negative - tabindex="-1" | Yes | Not in tab order, author must focus it with element.focus() as result of a key press. |
Adding a tabindex of -1 to an element allows the element to receive focus via JavaScript using the element.focus() method. This is used to allow arrow key navigation to elements. Each element that can be navigated to via arrow keys must have a tabindex of -1 to allow it to receive focus. A keydown event handler can determine the next object to receive focus and call that element’s focus() method. In addition, the style of the element may need to be updated in order to show the focus as brower’s are inconsistent in displaying focus for items that receive focus programmatically.
In order to assist with key event handling, an onkey event has been added to Dojo to normalize key events. The appropriate key event, either onkeydown or onkeypress, will be used depending upon the browser. The key codes have been normalized as well. See dojo.event.browser class in dojo.event.browser.js. In addtion, there is a special onDijitClick event implemented in the dijit system to provide support for a mouse click, Enter key press or Spacebar key press to invoke an action. By subscribing to the onDijitClick dijit event, the provided handler will be called when a click, enter key or space key is received allowing the developer to easily support both mouse and keyboard. This event is utilized by the core dijit widget set and is available to developers building custom widgets.
ARIA techniques (described in the Web Accessibilty section) allow creating sophisticated UI components using scripting which can be identified to assistive technology. In the future, user agents can also make use of this information to provide additional visual clues about components as well. For example, client side validation of a text entry component that was marked using the ARIA invalid attribute could be visually identified by the browser rather than requiring the developer to provide a specific style or text identification on the component.
The ARIA information is being added into the dijit widgets Methods have been added into dijit to enable setting the ARIA information. The roles and states for a widget can be set via the widget template or within the widget scripting code. The details of these methods are discussed later in this document. In addition to providing the roles and states for each component, there are some architectural considerations as well. For components that represent a hierarchy, such as a tree or menu, it is important to identify parent and child relationships. For items where position or count are important it may be necessary to hierarchically group elements or identify a set of related elements as a group. In some cases there are specific ARIA roles for grouping items such as treegroup for tree items within the same level. If no specific grouping role is provided the generic group role can be used.
Functions for dealing with accessibility are found in dijit._base.wai.js. The name of the file and object is derived from the W3C Web Accessibility Initiative which is hosting the ARIA specification. The dijit.wai APIs are used to manipulate ARIA roles and properties. In addition, the onload function to detect high contrast mode is part of dijit.wai.
The dijit.wai module is provided to normalize setting the roles and states. The ARIA techniques are designed to be used with XHTML via namespaces. Since a content-type of application/xhtml+xml is required to fully support namespaces an alternate solution is needed for the most commonly supported content-type of text/html. The roles and states can be manipulated using the DOM namespace apis: getAttributeNS, setAttributeNS, and removeAttributeNS. In browsers which do not support the namespace apis, the generic attribute apis, getAttribute, setAttribute, removeAttribute, are used and namespaces are simulated.
The dijit.wai module provides the necessary mapping of namespace information and attribute apis for each of the dijit.waiNames. It contains two submodules, waiRole and waiState, each with the following variables.
The dijit.wai methods getAttr(), setAttr(), and removeAttr() are wrappers to the appropriate attribute apis for the browser in use. These apis are called with the following parameters:
/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #000066; font-weight: bold;} .geshifilter .kw2 {color: #003366; font-weight: bold;} .geshifilter .kw3 {color: #000066;} .geshifilter .co1 {color: #009900; font-style: italic;} .geshifilter .coMULTI {color: #009900; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #3366CC;} .geshifilter .nu0 {color: #CC0000;} .geshifilter .me1 {color: #006600;} .geshifilter .re0 {color: #0066FF;}
The role and state can also be set via the widget template using the waiRole or waiState prefix. Setting the role in the template is the same as setting it via scripting – the dijit.wai.setAttr() method will be called during widget instantiation. Simply add the waiRole=”actualrole” or waiState=”state-value” parameters into the template markup for the element. The element will be passed as the nodeObj into the dijit.wai.setAttr() method. The state is specified as a state name and value pair, the state is separated from the value using the hyphen character (-): state-value. The state becomes the attribute name when dijit.wai.setAttr() is called. Multiple states can be set within the template by separating the state-value pairs with a comma. This mechanism is useful when templates are used to create the objects requiring a role value and when the state is known at creation time.
Here is an example of setting the role in the diijt tree template. The domNode is given the “tree” role.
/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #b1b100;} .geshifilter .kw2 {color: #000000; font-weight: bold;} .geshifilter .kw3 {color: #000066;} .geshifilter .coMULTI {color: #808080; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #ff0000;} .geshifilter .nu0 {color: #cc66cc;} .geshifilter .sc0 {color: #00bbdd;} .geshifilter .sc1 {color: #ddbb00;} .geshifilter .sc2 {color: #009900;}Functions for dealing with accessibility are found in dijit._base.wai.js. The name of the file and object is derived from the W3C Web Accessibility Initiative which is hosting the ARIA specification. The dijit wai APIs are used to manipulate ARIA roles and properties. In addition, the onload function to detect high contrast mode is part of dijit.wai.
The dijit wai module is provided to normalize setting the roles and states. The ARIA techniques are designed to be used with XHTML via namespaces. Since a content-type of application/xhtml+xml is required to fully support namespaces an alternate solution is needed for the most commonly supported content-type of text/html. The roles can be set directly by prefixing the role value with "wairole". States can be manipulated using the DOM namespace apis: getAttributeNS, setAttributeNS, and removeAttributeNS. In browsers which do not support the namespace apis, the generic attribute apis, getAttribute, setAttribute, removeAttribute, are used and namespaces are simulated.
There are separate dijit methods for querying, getting, setting, and removing ARIA roles and states.
The following dijit methods will set the role onto an element. The role parameter must be one of the possible ARIA role values.
/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #000066; font-weight: bold;} .geshifilter .kw2 {color: #003366; font-weight: bold;} .geshifilter .kw3 {color: #000066;} .geshifilter .co1 {color: #009900; font-style: italic;} .geshifilter .coMULTI {color: #009900; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #3366CC;} .geshifilter .nu0 {color: #CC0000;} .geshifilter .me1 {color: #006600;} .geshifilter .re0 {color: #0066FF;}
These dijit methods set the state values onto an element and are wrappers to the appropriate attribute apis for the browser in use. The state parameter must be a valid ARIA state name and the value the appropriate value for the specified state.
/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #000066; font-weight: bold;} .geshifilter .kw2 {color: #003366; font-weight: bold;} .geshifilter .kw3 {color: #000066;} .geshifilter .co1 {color: #009900; font-style: italic;} .geshifilter .coMULTI {color: #009900; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #3366CC;} .geshifilter .nu0 {color: #CC0000;} .geshifilter .me1 {color: #006600;} .geshifilter .re0 {color: #0066FF;}
The role and state can also be set via the widget template using the waiRole or waiState prefix. Setting the role in the template is the same as setting it via scripting – the dijit.setWaiRole() method will be called during widget instantiation. Simply add the waiRole=”actualrole” or waiState=”state-value” parameters into the template markup for the element. The element will be passed as the nodeObj into the dijit.setWaiRole() and dijit.setWaiState() methods. The state is specified as a state name and value pair, the state is separated from the value using the hyphen character (-): state-value. Multiple states can be set within the template by separating the state-value pairs with a comma. This mechanism is useful when templates are used to create the objects requiring a role value and when the state is known at creation time.
Here is an example of setting the role in the diijt tree template. The domNode is given the “tree” role.
/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #b1b100;} .geshifilter .kw2 {color: #000000; font-weight: bold;} .geshifilter .kw3 {color: #000066;} .geshifilter .coMULTI {color: #808080; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #ff0000;} .geshifilter .nu0 {color: #cc66cc;} .geshifilter .sc0 {color: #00bbdd;} .geshifilter .sc1 {color: #ddbb00;} .geshifilter .sc2 {color: #009900;}