[contents]
Copyright © 2007 - 2009 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
This WAI-ARIA Authoring Practices Guide provides readers with an understanding of how to use WAI-ARIA [WAI-ARIA] to create accessible rich internet applications. The principle objective is to produce a usable, accessible experience over the Web. It provides recommended approaches to create accessible Web content using WAI-ARIA roles, states, and properties to make widgets, navigation, and behaviors accessible. The document also describes considerations that might not be evident to most implementers from the WAI-ARIA specification alone. This document is directed primarily to Web application developers, but the guidance is also useful to user agent and assistive technology developers. This document is part of the WAI-ARIA suite described in the WAI-ARIA Overview.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This is a Public Working Draft by the Protocols & Formats Working Group of the Web Accessibility Initiative. It supports the Accessible Rich Internet Applications (WAI-ARIA) [ARIA] specification, providing detailed advice and examples beyond what would be appropriate to a technical specification but which are important to understand the specification. Most Web content developers seeking to accomplish particular tasks in rich Web content, and make their content accessible, should follow the approaches in this document to accomplish their task.
Feedback on the information provided here is essential to the ultimate success of Rich Internet Applications that afford full access to their information and operations. The PFWG asks in particular:
Follow the instructions for commenting page to submit comments. Submit comments online (preferred) or by email to to public-pfwg-comments@w3.org (Archive). Comments should be made by 2 February 2010. In-progress updates to the document may be viewed in the publicly visible editors' draft.
Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. The group does not expect this document to become a W3C Recommendation. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
The disclosure obligations of the Participants of this group are described in the charter.
This section is informative.
The WAI-ARIA Authoring Practices Guide is intended to provide readers with an understanding of how to use WAI-ARIA to create an accessible Rich Internet Application. As explained in the WAI-ARIA Primer, accessibility deficiencies in today's markup render rich internet applications unusable by people who use assistive technologies (AT) or who rely on keyboard navigation. The W3C Web Accessibility Initiative's (WAI) Protocols and Formats working group (PFWG) plans to address these deficiencies through several W3C standards efforts, with a focus on the WAI-ARIA specifications.
For an introduction to WAI-ARIA, see the Accessible Rich Internet Applications Suite (WAI-ARIA) Overview. The WAI-ARIA Authoring Practices Guide is part of a set of resources that support the WAI-ARIA specification. The practices describe recommended usage patterns for web content developers, and the WAI-ARIA Primer [ARIA-PRIMER] provides a basic introduction to the concepts behind and reason for WAI-ARIA. The WAI-ARIA suite fills gaps identified by the Roadmap for Accessible Rich Internet Applications (WAI-ARIA Roadmap) [ARIA-ROADMAP]. These documents serve as important places of clarification where topics appear to be unclear.
With the conceptual basis provided in the WAI-ARIA Primer, you should have a good understanding of how WAIARIA provides for interoperability with assistive technologies and support for a more usable, accessible experience. This guide begins by providing some general steps for building an accessible widget using WAI-ARIA, script, and CSS. It then extends your knowledge of WAI-ARIA with detailed guidance on how to make rich internet applications keyboard accessible. Next, the scope widens to include the full application, addressing necessary layout and structural semantics within the Web page. These semantics are critical to enable assistive technologies to provide a usable experience when processing rich internet applications with rich documents on the same page. It includes guidance on dynamic document management; use of WAI-ARIA Form properties; WAI-ARIA Drag and Drop; and then the creation of WAI-ARIA-enabled alerts and dialogs. The appendix provides substantial reference information including code samples for developers of user agents, assistive technologies, and Web pages.
WAI-ARIA markup is currently not included in (X)HTML. The W3C WAI PF working group will be creating DTDs for XHTML 1.0 and HTML 4.01 for those wishing to validate their markup with WAI-ARIA embedded into these host languages.
At this point you should have a basic understanding of how WAI-ARIA is used to support interoperability with assistive technologies. If you are not reusing a WAI-ARIA-enabled widget library and wish to create your own the following steps will guide you through the thought process for creating an accessible widget using WAI-ARIA.
Pick the widget type (role) from the WAI-ARIA taxonomy
WAI-ARIA provides a role taxonomy ([ARIA], Section 3.4) constituting the most common UI component types. Choose the role type from the provided table. If your desire was to create a toolbar set the role to toolbar:
<div role="toolbar">
Once you have chosen the role of your widget, consult the WAI-ARIA specification [ARIA] for an in-depth definition for the role to find the supported states, properties, and other attributes. For example, the toolbar
role definition includes:
toolbar
there are no such states or properties. However, in the case of a listbox
, you may choose to set the property of aria-multiselectable
to true if you were to have more than one item in the listitem
selected at a time. This indicates to the assistive technology that the listbox
manages a collection of selectable options.Once you have chosen the states and properties that apply to your widget you must set those properties you will use to set their initial values. Note: You do not need to use all the states and properties available for your role. In our case we shall use:
<div role="toolbar" tabindex="0" id="customToolbar" onkeydown="return optionKeyEvent(event);" onkeypress="return optionKeyEvent(event);" onblur="hideFocus()" onfocus="showFocus()" > <img src="img/btn1.gif" tabindex="0" title="Home" role="button" id="b1" alt="Home" onClick="updateText('Home was invoked');"> <img src="img/btn2.gif" tabindex="-1" title="Refresh" role="button" id="b2" alt="Refresh" onClick="updateText('Refresh was invoked');"> <img src="img/btn3.gif" tabindex="-1" title="Help" role="button" id="b3" alt="Help" onClick="updateText('Help was invoked');"> </div>
By avoiding tabindex
on the toolbar and setting tabindex=0
on the first button, but tabindex=-1
on the others, we have specified that the first button in the toolbar will receive focus in the document order. It is then necessary to use script to change the focus amongst the buttons from there.
Important: When embedding WAI-ARIA markup in (X) HTML, all WAI-ARIA states and properties must be preceded with the characters aria-
with the exception of the role
and tabindex
attributes. Otherwise, the user agent will not map the WAI-ARIA information, resulting in it not being recognized by assistive technologies.
When embedding WAI-ARIA into other host languages, tabindex
does not carry over. The WAI-ARIA tabindex
extensions are specific to (X)HTML to repair deficiencies in keyboard support.
Assistive technologies are very dependent on the structure of widgets as well as general document structure. Structure provides context to the user. A toolbar is a collection of common functions made available to the user. Therefore, all functions you would like in the toolbar must be contained within it. This can be determined by using the Document Object Model [DOM] tree structure created by the browser when parsing the host language. By using the parent child relationship of the DOM, an assistive technology can determine all the related toolbar widgets associated with the toolbar. The toolbar widgets would be DOM children of the "toolbar" container. For our purposes we will define three image buttons for cut, copy, and paste.
<div role="toolbar" tabindex="0" aria-activedescendant="button1"> <img src="buttoncut.png" alt="cut" id="button1"> <img src="buttoncopy.png" alt="copy" id="button1"> <img src="buttonpaste.png" alt="paste" id="button1"> </div>
We now need to assign the roles and states for each of the children. However, we shall save the detailed navigation for step 5.
<div role="toolbar" tabindex="0" aria-activedescendant="button1"> <img src="buttoncut.png" alt="cut" role="button" id="button1"> <img src="buttoncopy.png" alt="copy" role="button" id="button2"> <img src="buttonpaste.png" alt="paste" role="button" id="button3"> </div>
The process of setting roles and states may be a recursive procedure if the children themselves have children, such as in the case of an expandable/collapsible tree
widget.
Establish keyboard navigation of the widget and plan for how it will be navigated to within the document
It is very important that your widget be keyboard accessible. In fact, there must be a keyboard equivalent for every mouse operation. Where possible you should refer to the WAI-ARIA examples in this guide for tips on how to implement keyboard navigation for your widget. If you find that an example is not provided, you should follow standard keyboard bindings for UI components such as those used for the Java Foundation Classes for Windows 95/NT.
For our toolbar, we have chosen to have the toolbar manage the focus for its children and through the use of the aria-activedescendant
property. We have also chosen to have the toolbar receive focus based on the tab order by using tabindex
. In order to use aria-activedescendant
, each focusable descendant must have an assigned ID.
<head> <script> ... function optionKeyEvent(event) { var tb = event.target; var buttonid; DOM_VK_ENTER = 13; // Partial sample code for processing arrow keys if (event.type == "keydown") { if (event.altKey) { return true; // Browser should use this, the menu view doesn't need alt-modified keys } // XXX Implement circular keyboard navigation within the toolbar buttons if (event.keyCode == DOM_VK_ENTER) { ExecuteButtonAction(getCurrentButtonID()); // This is an author defined function } else if (event.keyCode == event.DOM_VK_RIGHT) { // Change the active toolbar button to the one to the right (circular) by var buttonid = getNextButtonID(); // This is an author defined function tb.setAttribute("aria-activedescendant", buttonid); } else if (event.keyCode == event.DOM_VK_LEFT) { // Change the active toolbar button to the one to the left (circular) by var buttonid = getPrevButtonID(); // This is an author defined function tb.setAttribute("aria-activedescendant", buttonid); } else { return true; } return false; } else if (event.type == "keypress") { ... } } </script> <div role="toolbar" tabindex="0" aria-activedescendant="button1" id="tb1" onkeydown="return optionKeyEvent(event);" onkeypress="return optionKeyEvent(event);"> <img src="buttoncut.png" alt="cut" role="button" id="button1"> <img src="buttoncopy.png" alt="copy" role="button" id="button2"> <img src="buttonpaste.png" alt="paste" role="button" id="button3"> </div>
The details of implementing keyboard navigation are described in Keyboard and Structural Navigation section of this document.
Note: You must also show the visual focus for each element that has focus.
Apply and manage needed WAI-ARIA states in response to user input events
Similar to the processing of aria-activedescendant
in Step 5, as author you must set any additional WAI-ARIA states and properties on document elements.
Synchronize the visual UI with accessibility states and properties for supporting user agents
You should consider binding user interface changes directly to changes in WAI-ARIA states and properties, such as through the use of CSS attribute selectors. For example, the setting of the aria-selected
(state) state may change the background of a selected treeitem
in a tree
. This may also be done with JavaScript.
.treeitem[role="treeitem"][aria-selected="true"] {color: white; background-color: #222222;} .treeitem[role="treeitem"][aria-selected="false"] {color: white; background-color: beige;}
Authors should be aware that CSS attribute selectors are not supported in some browsers, such as Internet Explorer 6. A consistent way to apply styling to reflect WAI-ARIA semantics would be to assign an element a class name based on the WAI-ARIA attribute being set using script as shown here:
function setSelectedOption(menuItem) { if (menuItem.getAttribute("role") != "menuitem") { return; } var menu = getMenu(menuItem); var oldMenuItem = getSelectedOption(menu); // Set class so that we show selection appearance oldMenuItem.className="unselected"; menu.setAttribute("aria-activedescendant", menuItem.id); menuItem.className= "selected"; }
The proper synchronization of showing and hiding sections in a widget with the WAI-ARIA display state is also critical. Some platform accessibility APIs provide events for applications to notify the assistive technology when pop-ups such as menus, alerts, and dialogs come into view or go away. Rich Internet applications can assist browsers which support these conventions by:
Creating an entire section and then insert it into the Document Object Model [DOM], as a subtree of the parent element activated to show the pop-up, and then removing the section from the inserted area when the pop-up goes away.
OR
Using the following style sheet properties to show and hide document sections being used to represent the pop-up items, menus or dialogs:
display:block
display:none
visibility:visible
visibility:hidden
By monitoring these behaviors a user agent may use this information to notify assistive technology that the pop-up has occurred by generating the appropriate accessibility API event.
Some assistive technologies may use the DOM directly to determine these when pop-up occurs. In this case, the first mechanism of writing a section to the DOM would work using the DOM events as demonstrated here.
// create new table row with table cell and div var newTr = document.createElement('TR'); var newTd = document.createElement('TD'); var newDiv = document.createElement('DIV'); newTr.appendChild(newTd); newTd.appendChild(newDiv); //insert this new table row before the Node selected var container = theNode.parentNode; container.insertBefore(newTr, theNode); //remove theNode selected container.removeChild(theNode);"
However, if you are using CSS to show and hide sections of the DOM (2) it is essential that you set the corresponding WAI-ARIA aria-hidden
(state) property to indicate that the section is visible or hidden and synchronize it with your CSS styling as shown here:
[aria-hidden=true] {visibility: hidden;} ... <div role="button" aria-haspopup="true" aria-owns="mypopupmenu"> <div role="menu" aria-hidden="true" id="mypopupmenu">...</div>
When an image is used to represent information within a component, such as image buttons, you need to set the alternative text on those images. This is then mapped by the user agent to the accessible name in the platform accessibility API. Using our example:
<div role="toolbar" tabindex="0" aria-activedescendant="button1" id="tb1" onkeydown="return optionKeyEvent(event);" onkeypress="return optionKeyEvent(event);"> <img src="buttoncut" role="button" id="button1" alt="cut"> <img src="buttoncopy" role="button" id="button2" alt="copy"> <img src="buttonpaste" role="button" id="button3" alt="paste"> </div>
Once you have made the basic widget accessible you may then need to establish its relationship to other widgets. Examples of this are aria-labelledby
, aria-controls
, aria-describedby
and aria-flowto
. The details of using these relationships are described in the Relationships section of this document.
Other relationships which should be considered are more declarative and provide context to the widget within a set. For these, aria-level
, aria-posinset
, and aria-setsize
are provided. If you structure your Document Object Model appropriately so that the user agent can determine this information from it using the DOM hierarchy directly, you do not need to set these properties. There are, however, situations in rich internet applications where all the elements in a container are not in the DOM at one time, such as when you can only render the ten of fifty items in a subtree. In this case the user agent cannot determine the number of tree items (aria-setsize
) for the position in the set (aria-posinset
), and potentially the tree depth (aria-level
) from the DOM. In these situations you will need to provide these WAI-ARIA properties.
Review widget to ensure that you have not hard coded sizes
The ability for applications to respond to system font settings is a requirement. Most user agents are designed to meet this requirement. This also means your Web application running within your browser is impacted when the user agent changes the font sizes to meet the need. If you have hard coded your font size in pixels an increase in system fonts will not be reflected in your Web application. You must also not hard code the size of your widgets in pixels either. If the fonts are scalable, but the widget they are encapsulated in is not, then the text could flow outside your widget.
Follow these rules to allow your application to respond to system font settings:
Percentages are the most reliable way to consistently specify proportional text sizes in widgets. The use of percentages and em should be used for specifying widths of a widget and the widget sub components. The use of percentages for text size and percentages and em units for widths support browser zoom capabilities to make widgets larger or smaller. Pixels can be used for specifying line widths, padding and margins.
Important: Most browsers today have a zoom feature which allow the user to magnify the entire Web page. Most legislation today requires that your application respond to system font and color settings and therefore you will want to consider the fact the system settings could adversely affect your Web page should you decide to hard code pixel sizes.
To ensure you have set your WAI-ARIA semantics correctly, test your application with your user agent, an assistive technology, and a person with disability. Example assistive technologies are screen readers and screen magnifiers. Ensure that your user agent is designed to support WAI-ARIA and their your assistive technology is designed to support WAI-ARIA in the selected user agent.
Finding people with disabilities to do testing may be difficult but many companies employ people with disabilities, including your customers, and you should reach out to them to ask for help. Other places to look are advocacy groups like the National Federation of the Blind or your local schools for the blind, reading and learning centers, and so on. The people you reach out to may someday need to use what you produce.
Providing an effective navigation experience to the user is critical for usability. This section starts with guidance on how to provide effective keyboard navigation for widgets in a Rich Internet Application environment. This includes a discussion on how to manage keyboard focus and the specifics on providing keyboard navigation for tooltips. This is is followed by a broader discussion on how to convey structural semantics for the entire Web page. These semantics help an assistive technology provide additional navigation, increase user productivity, and render the page in an alternative formats. This rendering may be in different forms, including but not limited to speech, page restructuring, and alternative input solutions.
One way to provide keyboard support in (X)HTML is with form and list elements that accept keyboard focus by default. With the Tab key, the user can navigate to these types of elements. However, when building sophisticated widgets, it's necessary to be able to control keyboard navigation exactly. Authors may require or prefer to use host language elements that do not have built-in keyboard navigation features. For example, the author may wish to provide keyboard navigation without altering the tab order. Navigating within large composite widgets such as tree views, menubars, and spreadsheets can be very tedious and is inconsistent with what users are familiar with in their desktop counterparts. The solution is to provide full keyboard support using the arrow keys to provide more intuitive navigation within the widget, while allowing Tab and Shift+Tab to move focus out of the widget to the next place in the tab order.
A tenet of keyboard accessibility is reliable, persistent indication of focus. The author is responsible, in the scripts, for maintaining visual and programmatic focus and observing accessible behavior rules. Screen readers and keyboard-only users rely on focus to operate rich internet applications with the keyboard.
One requirement for 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. Originally implemented in Internet Explorer 5, the feature has been extended to Opera, Firefox, and Mozilla. The following table outlines the use of the tabindex attribute:
Tabindex Attribute | Focusable with mouse or JavaScript via element.focus() | Tab Navigation |
---|---|---|
not present | Follows default behavior of element (only form controls and anchors can 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 | No, author must focus it with element.focus() as a result of arrow or other key press |
Setting a tabindex value of -1 to an element enables the element to receive focus via JavaScript using the element.focus() method. This method is used to enable arrow key navigation to elements. Each element that can be navigated to via arrow keys must have a tabindex of -1 to enable it to receive focus. Here are just a few additional tips to help you with managing keyboard focus:
Use focus and blur events (or event delegation) to track the current focus - focus
and blur
events can now be used with every element. There is no standard DOM interface to get the current element with keyboard focus, so authors may keep track of it with a JavaScript variable. Don't assume that all focus changes will come via key and mouse events, because assistive technologies such as screen readers can set the focus to any focusable element, and that needs to be handled elegantly by the JavaScript widget. Techniques such as "event delegation" (for example, intercepting events on a list rather than on every listitem) can greatly increase web application performance and code maintainability, and authors are encouraged to use JavaScript best practices whenever possible.
Follow keydowns to move focus - A keydown event handler can determine the next object to receive focus and call that element's focus() method.
Use onkeydown to trap key events, not onkeypress - Key press events do not fire for all keys and they vary across browsers.
Dynamically change focusability using the tabIndex property - You may want to update tabindex values if a custom control becomes disabled or enabled. Disabled controls should not be in the tab order. However, you can typically arrow to them if they're part of grouped navigation widget. When an element receives focus, it should change the tabindex value to 0 to make an element the default element of the widget. This is important if the user leaves the widget and returns to the widget again so focus is on the last element of the widget the user was on. If other elements of a widget can receive keyboard focus, only one element of the widget should have a tabindex value of 0.
Use element.focus() to set focus - Do not use createEvent(), initEvent() and dispatchEvent() to send focus to an element, because these functions do not change the focus. DOM focus events are informational only, generated by the user agent after an element has acquired focus, but not used themselves to set focus.
The use of :focus pseudo-class selectors to style the keyboard focus is not supported in many versions of Internet Explorer. Authors should use the :active pseudo-class (which older versions of IE treat like :focus) in conjunction with the :focus pseudo-class. Example: a:focus, a:active { text-decoration: underline; }
If the related CSS pseudo-classes are not appropriate or not supported in all browsers, authors can use JavaScript techniques to indicate an appropriate focus alternative, such as using focus and blur events to toggle a classname on an element.
Always draw the focus for tabindex="-1" items and elements that receive focus programmatically when supporting versions of Internet Explorer older than 8 - Choose between changing the background color via something like this.style.backgroundColor = "gray"; or add a dotted border via this.style.border = "1px dotted invert". In the dotted border case, you will need to make sure those elements have an invisible 1px border to start with, so that the element doesn't grow when the border style is applied (borders take up space, and IE doesn't implement CSS outlines).
Prevent used key events from performing browser functions - If a key such as an arrow key is used, prevent the browser from using the key to do something (such as scrolling) by using code like the following:
<span tabindex="-1" onkeypress="return handleKeyPress();">
If handleKeyDown() returns false, the event will be consumed, preventing the browser from performing any action based on the keystroke. In addition to the return value the browser must call the event methods that will prevent the default action, for IE this is setting the event property "returnValue=false", and for other browsers supporting the W3C event model this means calling the "preventDefault" method of the event object.
<span tabindex="-1" onkeydown="return handleKeyDown();">
If handleKeyDown() returns false, the event will be consumed, preventing the browser from performing any action based on the keystroke.
Use key event handlers to enable activation of the element - For every mouse event handler, a keyboard event handler is required. For example, if you have an onclick="doSomething()" you may also need onkeydown="return event.keyCode != 13 || doSomething();" in order to allow the Enter key to activate that element.
Note: There are user agent-specific considerations for key event handling.
Consider using a "roving" tabindex for complex widgets if you are not using the aria-activedescendant
property.
In addition to tabindex, WAI-ARIA provides the aria-activedescendant
property for managing the focus of child elements within a widget. Widgets like grid
and tree
typically manage their children. The root element of the widget should have a tabindex
value greater than or equal to "0" to ensure that the widget is in the document tabbing order. Rather than setting a key event handler on each element within a larger component, the event handler can be set on the parent element such as the tree. It is then the job of the parent element to manage the focus of the children.
The parent may use the aria-activedescendant
property to indicate the active child. For example, the container element with the role of tree can provide an onkeydown event handler so that each individual tree item within the tree does not need to be focusable and to listen for the keydown event. The container object, in this case the tree, needs to maintain the point of regard and manage which individual child item must be perceived as active.
Important: For a given container widget where activedescendant must cause focus events to be fired to ATs, the actual focus must be on the container widget itself. In HTML this is done by putting tabindex="0" on the container widget.
The key handler on the parent captures the keystrokes and determines what item becomes active next and updates the aria-activedescendant
property with the ID of the appropriate, next active child element. The browser takes that ID information and generates the focus event to the assistive technology. Each individual element does not have to be made focusable via a tabindex
value of -1, but it must be styled using CSS to indicate the active status
An alternative to using activedescendant is to have the parent element, in response to the same keyboard input, move focus to its children by first removing tabindex
from children that do not have focus, which removes them from the tab order. This would be followed by setting the tabindex
to "-1" on the element that is to receive focus and then using script to set focus on the element to receive focus. As with aria-activedescendant
, this omits managed children from the tabbing order. It enables browsers that do not yet support aria-activedescendant
to maintain keyboard navigation, and it provides notification to many assistive technologies like screen magnifiers to move visual focus without relying on other WAI-ARIA properties. Today, this technique will work in most user agents, but in the long run aria-activedescendant
will require less work by the developer.
Although not always ideal based on the widget you are creating, one benefit of using tabindex to manage focus on an element is that the user agent will scroll the element into view when focus is set to the it. This is not the case for aria-activedescendant
. When setting or updating the aria-activedescendant
property, e.g. aria-activedescendant="cell23"
, authors must ensure that the element with id="cell23"
is in view. In either case, consider positioning your widget in the visible area of your browser to maximize usability. This can be achieved using available JavaScript scrolling functions.
In some browsers, a JavaScript call to scrollIntoView()
on this element should suffice, but in browsers where this is unreliable, authors should explicitly set the scrollTop
and scrollLeft
properties of the "cell23" element and its ancestors to scroll the element into view. scrollTop
and scrollLeft
adjust the node positions by the amounts(pixels) needed to scroll a node into view. Scrolling values are adjusted by the amounts(pixels) needed
to scroll a node into view. This is done by comparing the sizes of the nodes
using available measurements such as scroll+offset+clientWidth/Height/Left/Top. It's important to note that you have to adjust a node so that it's viewable within
the context of its parent node. Then you have to move up the DOM tree and make
each parent node visible.
For example, create a custom scrollIntoView()
method that is called at various times, including coincidence with the setting of the aria-activedescendant
property. The method takes a DOM node argument, say "n". Here is the high level algorithm:
This is a minimum-position-change algorithm.
Understanding how the DOM scrollIntoView works across browsers is important. Browsers (including Firefox3) force the node either to the top or the bottom of the screen (as defined by the single Boolean parameter) even if its already in view. This is problematic when you only need to scroll horizontally to see the element. It is also problematic when the node is partially off the bottom of the screen and the parameter is (true) which forces the node all the way to the top, and vice versa with the top going to the bottom on (false). IE forces the node to the left of the client area (or right in right-to-left mode) even if it's horizontally in view already.
The scrollTop
and scrollLeft
functions create some challenges. scrollTop
is always accurate but misleading with respect to inner (nested) scrollbars. scrollLeft
cannot be relied on in right-to-left languages because it is sometimes negative and sometimes positive especially with respect to inner (nested) scrollbars. Different browsers handle right-to-left completely differently.
Often applications give the perception of having a dual focus. Two examples of this are multi-selection list boxes and selected tabs, within a tablist, when focus is in a tabpanel. In the case of a muti-selection list box a developer may gray selected items as they move focus to list box items to toggle their selected state. In the case of a tabpanel
the user selects a tab but then navigates to a focused item in the corresponding tabpanel
the tab appears to also have focus. In reality, only one element may have focus in an application. In these scenarios authors should ensure keyboard focus is set on the current element that visibly receives keyboard user input while ensuring other "highlighted" elements have an aria-selected state of "true" until de-selected. When the de-selection occurs, such as when a multi-select item is de-selected or a user moves to a new tab and de-select the old tab, the author should ensure that the visible selection of the de-selected item is removed.
Author-defined keyboard short-cuts or mnemonics present a high risk for assistive technology users. Because they are device-, browser-, and AT-dependent, conflicts among key bindings are highly probable. Therefore, if you needed to use accesskey, you should be aware that it will behave differently in
different browsers. It also may not work with small devices so it is still advisable to ensure that all features are accessible with the basic keys like Tab/shift+tab, arrow, Enter, space and Escape.
The XHTML 2 Working Group is currently developing a new Access Module to address this issue and we hope to have it or a feature like it in future versions of (X)HTML. Refer to Section 9: Implementation Guidance.
A tooltip
is a popup messages typically triggered by moving a mouse over a control or widget causing a small popup window to appear with additional information about the control. To provide simple text tooltips, the HTML title attribute should more than suffice because the user agent will render it for tooltips. When creating a tooltip
, it is essential that the user be able to activate it using the keyboard. When a form control or widget receives keyboard focus, the tooltip
must display. When the form control or widget loses focus, the tooltip must disappear. Browsers do not currently support this functionality.
The following code snippet from the iCITA site shows the use of a onfocus="tooltipShow() function to display the tooltip when focus is placed on an element.
<html lang="en-us"> <head> <title>inline: Tooltip Example 1</title> <link rel="stylesheet" href="css/tooltip1_inline.css" type="text/css"> <script type="text/javascript" src="js/tooltip1_inline.js"></script> <script type="text/javascript" src="../js/widgets_inline.js"></script> <script type="text/javascript" src="../js/globals.js"></script> <link rel="icon" href="http://www.cites.uiuc.edu/favicon.ico" type="image/x-icon"> <link rel="shortcut icon" href="http://www.cites.uiuc.edu/favicon.ico" type="image/x-icon"> </head> ... <body onload="initApp()"> <div id="container"> <h1>Tooltip Example 1</h1> <h2>Create Account</h2> <div class="text"> <label for="first">First Name:</label> <input type="text" id="first" name="first" size="20"" onmouseover="tooltipShow(event, this, 'tp1')" onfocus="tooltipShow(event, this, 'tp1');" aria-describedby="tp1" aria-required="false"/> <div id="tp1" role="tooltip" aria-hidden="true">Your first name is optional. </div> </div> ...
Similar to the tip specified in Using Tabindex to Manage Focus on Widgets, a web application should cancel (or swallow) the keyboard event in the keyboard handler to prevent the key from being used outside the web application. For example if the user presses Control+PageDown in a tab panel in a web application, this keyboard event should not also go to the user agent, which would cycle the active browser tab, confusing the user.
This section takes a broader look at the Web page. It is intended to assist you in conveying a logical, usable, and accessible layout to an assistive technology or adaptive system designed to modify the visual layout to meet the users needs.
One of the deficiencies of (X)HTML for disabled users has been the usability of keyboard navigation. Users dependent on a keyboard for navigation have been forced to tab everywhere in the document, as the only keyboard accessible document elements are form and anchor elements. This has forced developers to make most everything a link to make it keyboard accessible, and to get to each link you have to tab to it. With the advent of portals and other content aggregation means Web pages are divided into visible regions and there has been no vehicle to get to them other than perhaps to do things such as:
<H1>
tag There are number of problems with this approach:
<H1>
to mark your regions, this is not consistent across Web sites This remainder of this section provides the author with a playbook for using WAI-ARIA to add semantically rich navigation structure in a Web page so that an assistive technology may provide an effective user experience and avoid these shortcomings.
Follow these steps to mark each logical section:
Identify the logical structure of your page
Break up your page into perceivable block areas which contain semantically associated information called "regions". You can further break down each region into logical regions as needed. This is a common process undertaken by portal developers who break the page into perceivable regions called portlets. Think about the user wanting to navigate to these logical block areas on your Web page. Write down a description of what you believe each region to be.
Depending on your Web application you may then need to break it into sub regions depending on the complexity of your Web application. This is a recursive process. A user will look at these perceivable areas like pealing an onion. You might have an outermost collection of perceivable regions or block areas and upon entering each region you may have a collection of regions within it.
Implement the logical structure in markup
Implementing the block structure in markup often involves wrapping elements contained with a "region" such as a <div>
or <iframe>
with visible borders so that each region or block is perceivable to the user.
Once you have broken up each region you need to label it. The start of each region must have a perceivable header and it should be used to label the region. For details on how to do this see section 3.4.3.1 Header Levels vs. nesting level to create a header to label each region. If you're finding it difficult to come up with a label for the region, make sure at least to use one of the standard roles defined in the following step. The drawback of not providing a label is that users will not know the purpose of the region. By definition, regions would be included in a summary of a page. If an assistive technology were to summarize it would be unable to provide information about the section without a label.
Assign landmark roles to each region
Now that you labeled your regions, you need to assign them semantic navigation landmarks. Landmarks are a vast improvement over the rudimentary "skip to main content" technique employed prior to WAI-ARIA. If possible it is best to use these as landmarks. Skip to main content links may impact the placement of web application elements. This may be a consideration for developers that want to try to keep their web application in a specific visible area. Consequently, layout adjustments may need to be made to support skip to main content links. Also, skip to main content links are limited in that they only address only one main content area. WAI-ARIA provides a collection of landmarks which are applied to each of the regions you identified in step 2.
The presence of common, semantic, navigation landmarks allows each site to support the same standard and allows your assistive technology to provide a consistent navigation experience - an important feature for screen readers and alternate input solutions. For users with cognitive and learning disabilities the landmark information could be used to expand and collapse these regions of your page to aid in simplifying the user experience by allowing the user to manage the amount of information processed at any one time.
There are also mainstream benefits of providing navigation landmarks. Your browser may assign key sequences to move focus to these sections as they can be set on every site. Navigation to these landmarks is device independent. A personal digital assistant (PDA) could assign a device key to get to them in your document. The common landmarks in WAI-ARIA include:
application
If the entire web page has a role of application then it should not be treated as a navigational landmark by an assistive technology.
banner
complementary
contentinfo
main
navigation
search
To set the landmark in your page:
<div role="log" title="chat log"> <div role="region" title="Game Statistics">
If you have a regional landmark of type application and static descriptive text is available, then on the application landmark, include an aria-describedby reference to associate the application and the static text as shown here:
<div role="applicaton" aria-labelledby="calendar" aria-describedby="info"> <h1 id="calendar">Calendar<h1> <p id="info"> This calendar shows the game schedule for the Boston Red Sox. </p> <div role="grid"> .... </div>
You can create custom regional landmarks by using a generic region
. While it is not essential to label these specialized regions with a header, you should provide a title to ensure that the region name is accessible to all users, just as you would the standard regional landmarks. See Header levels versus Nesting levels for directions on how to label the region.
<div role="main"> ... <div role="region" title="weather">
Note: the region
role is generic and should only be used when a more specific role is not applicable.
Indicate to the assistive technology who controls the keyboard navigation
Today's screen readers for the blind have been designed to give the user a "browsing" experience meaning the screen reader consumes a number of keys to aid in the browsing experience. For example, the "up" and "down" arrow keys are used to read the next and previous line of text on your Web page. Accessible rich internet applications will use these keys in an application to navigate within "widgets" like a Tree View.
Assistive technologies must be able to identify widgets which implement WAI-ARIA and allow them use of the keyboard. However, if you have used numerous widgets to form an application you must set the role on the encompassing region to application
. Should you have regions which should be browsed as documents within the application region you should mark those regions with a document
role as needed. See section 3.4.2 Structural Roles used to facilitate assistive technology navigation.
When viewing Web content however, screen readers often gather information about all the widgets in an area and present them in a document-like view which the user navigates using keyboard commands provided and controlled by the screen reader. Think of this mode as a virtual environment that presents Web content in a way that makes it convenient for adaptive technology users to navigate and read. This is sometimes called browse mode, or virtual mode. We refer to this as "document browse mode."
Because many screen readers provide document mode navigation support using single key mnemonics on the alpha-numeric keyboard, they may provide a third mode, called "forms mode," used to interact with form controls that are encountered in document mode. Behavior in forms mode is similar to that of application mode. The key feature of forms mode is that it can be toggled with document mode to make it easy to both interact with a specific widget, and read virtualized content of which the widget is a part. Since, as described above, a screen reader's perception of an area as either a document or an application greatly influences how the user reads and interacts with it, WAI-ARIA provides content authors a way to indicate whether their pages must be viewed as applications or documents by assistive technologies.
To set document or application mode follow these steps:
After you have divided your Web page into regions through the use of role landmarks and custom regions, you must make a decision: Is your Web page an application or not? If the majority of the content is application-like the default interaction mode should be set to application
, with document
regions embedded within the application if applicable. Otherwise the default interaction mode is document-like and therefore should not be overridden by the use of a global role of application
. In this case the application
role can be placed on discrete regions within the document if applicable.
If it is, set the role of application
on the body tag as follows:
<body role="application">
When using application
, all static text must be associated with widgets, groups or panes via using the aria-labelledby
and aria-describedby
properties, otherwise it will not be read by the screen reader when the user navigates to the related widget or group.
Special Considerations:
application
. WAI-ARIA provides dialog
and alertdialog
roles that are to be treated as special case application
roles. Like application, screen readers will leave the main job of keyboard navigation up the dialog.
When using dialog
, all static text must be associated with widgets, groups or panes using the aria-labelledby
and aria-describedby
properties, otherwise it will not be read by the screen reader when the user navigates to the related widget or group. Unlike an application, your Web page is unlikely to start out as either of these two roles but rather the author is most likely to dynamically create dialogs or alertdialog sections within the Web page.
Unlike dialog
, descriptive text of the alert does not need to be associated via a relationship, as the contents of alert dialogs will be read automatically by the screen reader when the dialog opens.
The default mode for a screen reader to be processing an HTML Web page is document browse mode. This is equivalent to having a role of document on the HTML
<body>
tag. If you have already specified a role of application on the body tag there may be times in which you tell the screen reader to switch into "document browse mode" and start stealing the necessary keys to browse a document section of your Web page. These keys are the typical keys used by WAI-ARIA widgets and to provide this level of navigation the keys must be stolen from your browser.To mark areas of your page to tell the assistive technology when to switch into document browse mode, look at the regions/landmarks you have defined and determine which ones must be browsed as a document or navigated as an application. For each region which must be browsed in document browse mode, embed a div element within it with the role of
document
as follows:<div role="document">Now, when a screen reader encounters this region, it will change its interaction model to that of document browsing mode.
This section discusses the use of the heading
role and nesting levels.
The heading
role value signifies a heading for a section of the document instance. Use of the heading role indicates that a specific object serves as a header. The region
of the document to which the heading pertains to should be marked with the aria-labelledby
property containing the value of the id for the header. If you have a heading and there is no element containing the content that it heads, wrap the content in a <div> bearing this aria-labelledby
attribute. If headings are organized into a logical outline, the aria-level
property can be used to indicate the nesting level. Here is an example:
<p role="main" aria-labelledby="hdr1"> <div role="header" id="hdr1" aria-level="1"> Top News Stories </div> </p>
Assistive technology briefs users on the context where they are. When they arrive at a new page, a page summary may be given. When they move into a new context, some of the labeling from elements containing the new focus or reading location may be rendered by the assistive technology, to give context to the details to be read next.
The syntactic structure of a page provides the default nesting of contexts. If a paragraph is nested in a <div> or table cell, it is assumed that labels for the <div> or headers for the table cell are pertinent to what is in the paragraph. On the other hand, it is not possible to always flow the logical structure one-to-one into the parse structure.
The aria-owns
relationship is provided to annotate logical nesting where the logical child is not a syntactic descendant of the logical parent. In a Rich Internet Application, updates may be made to the document without updating the logical syntactic structure, yet elements may appear to be added to the document structure. From a DOM and accessibility hierarchy perspective aria-owns
is a fallback mechanism to using the tree hierarchy provided in the DOM. An example of where aria-owns
is needed is a treeitem
, where children in a folder subtree are added to a visible subtree but not reflected in the actual document subtree of the folder. The aria-owns
relationship can be used to associate the folder with the new "adopted" child. For more details on the use of aria-owns
see section 4.2 Owning and Controlling. The aria-owns
relationship is used to indicate to a user agent that a menu is an adopting parent of a sub menu
. Another use for aria-owns
is a hierarchical diagram where the child nodes of the diagram are not be adequately represented using the DOM structure.
There are several WAI-ARIA roles used to indicate a collection of user interface objects, and each has a distinct purpose:
directory
group
region
The use of each is described below.
The WAI-ARIA role, directory
, allows authors to mark static table of content sections of a document. Prior to WAI-ARIA, the user would need to guess if an area of a document actually pertained to the table of contents. Authors should mark these sections within a document with a role of directory.
<div role="directory"> <ul> <li>Global Warming Causes <ul> <li>CO2 Buildup</li> <li>Auto emissions<li> <li>Factory emissions</li> <li>Destruction of rainforests</li> </ul> </li> <li>Tailoring CO2 buildup <ul> <li>Elimination of the incandescent light bulb</li> <li>Hydrogen fuel cells</li> <li>Solar energy</li> <li>Wind power</li> </ul> </li> </ul> </div>
Authors should use a role of group
to form logical collections of items with related functionality in a widget. A group should not be considered a major perceivable section on a page. A group
neither has a heading nor appears in the "Table of Contents." A group
may delineate a set of treeitem
s having the same level in the tree
or it may be used to group a set of related checkboxes in a form. Other examples include:
row
in a grid (a row is a specialized group representing a row in a grid); group
of children in a tree widget forming a collection of siblings in a hierarchy; or group
of items having the same container in a directory Proper handling of a group by assistive technologies, therefore, is determined by the context in which it is provided. Group members that are outside the DOM subtree of the group need to have explicit relationships assigned for them in order to participate in the group. Groups may also be nested.
If an author believes that a section is significant enough in terms of the entire document instance, then the author must assign the section a role of region or one of the designated standard XHTML Role landmark. The designated landmark roles are listed in the section Regions and XHTML Role landmarks..
When defining a region for a section of a document, authors must consider using standard document landmark roles defined by the XHTML Roles Module. This makes it possible for user agents and assistive technologies to treat roles as standard navigation landmarks. If the definition of these regions is inadequate, authors must use the WAI-ARIA region
role and provide the appropriate title text.
For more information on the use of region see Regions and XHTML Role landmarks.
A number of structural roles support the tabular widgets, grid
and treegrid
. These structural roles indicate additional keyboard navigation as well as the ability to select rows and/or columns. Typically, you would apply these roles to an underlying table in the base markup as shown here:
<table role="grid">
However, that may not work for the developer in all instances, such as when the developer has need for a <div> or <span> or when additional semantics are needed. To assist, the following roles are provided to support tabular widgets:
When constructing a grid
or treegrid
the author must use gridcell
s for the actual cells:
<table role="grid"> <tr> <td role= "columnheader">Apples</td><td role= "columnheader">Oranges</td> </tr> <tr> <td role="gridcell">Macintosh</td><td role="gridcell">Valencia</td> </tr> </table>
Unlike table cells within a table, authors should ensure a grid's gridcell
s are focusable through the use of tabindex (in HTML), or aria-activedescendant
on the grid.They may also be editable, as is shown in the above example.
Treegrid's may require expanding and collapsing rows which may not be performed using a <tr>. In these instances authors will use an HTML <div>
. WAI-ARIA provides a role of row
which may be assigned to the <div>
to convey to the assistive technology that this is still a row. If you decide to not use the native HTML <table> elements and choose more flexible elements, such as <div>
and <span>
s, with applied WAI-ARIA roles in this section, you should structurally lay out your elements in line with what you would expect from HTML. All of your rowheader
s should be in a row
and your gridcell
s should be children of each subsequent row in the same format as HTML for <td>
s and <th>
s within <tr>
s.
A new feature of WAI-ARIA is the ability to associate descriptive text with a section, drawing, form element, picture, and so on using the aria-describedby
property. This is unlike longdesc which typically required the author to create a separate file to describe a picture when it was preferred to have the descriptive text in prose as well so that it was readily available to all users. Yet, like longdesc descriptive text is treated separately from the short name you would typically provide using the title or alt attributes in HTML.
<img src="foo" alt="abbreviated name" aria-describedby="prose1"> <div id="prose1"> This prose in this div describes in detail the image foo. </div>
This is the preferred vehicle for providing long descriptions for elements in your document.
In order to be synchronized with the XHTML Role Attribute module, WAI-ARIA includes two XHTML roles which are neither landmarks or widgets of any kind. These roles were incorporated to replace standard elements found in host languages. These roles are definition
and note
. If either role has a corresponding element in the host language it recommended that authors use the corresponding element in the host language.
The definition
role indicates a definition statement in your document. For HTML developers implementing lists of definitions, we recommend you using the DL, DT, and DD elements rather than marking an arbitrary element with a role of definition. An arbitrary element would be appropriate for inline definitions used in conjunction with the DFN element.
Example of an inline definition with an explicit labelledby relationship:
<p>The doctor explained it had been a <dfn id="placebo">placebo</dfn>, or <span role="definition" aria-labelledby"placebo"> or an inert preparation prescribed more for the mental relief of the patient than for its actual effect on a disorder.</span> </p>
Example inline definition with an implicit labelledby relationship determined by nesting:
<p>The doctor explained it had been a <span role="definition"> <dfn>placebo</dfn>, an inert preparation prescribed more for the mental relief of the patient than for its actual effect on a disorder.</span> </p>
Note: In the case where host language semantics do not allow for implicit nesting of definitions terms inside definition roles, authors should explicitly use the aria-labelledby attribute, even when the definition term is nested in the definition as shown here:
<p>The doctor explained it had been a <span role="definition" aria-labelledby="placebo"> <dfn id="placebo">placebo</dfn>, an inert preparation prescribed more for the mental relief of the patient than for its actual effect on a disorder.</span> </p>
The following is an example using a definition list:
<dl> <dt id="anathema">anthema</dt> <dd role="definition" aria-labelledby="anathema">a ban or curse solemnly pronounced by ecclesiastical authority and accompanied by excommunication</dd> <dd role="definition" aria-labelledby="anathema">a vigorous denunciation : cursor</dd> <dt id="homily>homily</dt> <dd role="definition" aria-labelledby="homily">a usually short sermon</dd> <dd role="definition" aria-labelledby="homily">a lecture or discourse on or of a moral theme</dd> </dl>
The note
role defines a parenthetic or ancillary remark to the main
content of the resource. It also allows assistive technologies to skip over this section of the document unless more information is requested about the main content.
<div role="main" aria-labelledby="foo"> <h1 id="foo">Wild fires spread across the San Diego Hills</h1> Strong winds expand fires ignited by high temperatures ... </div> <div role="note"> This article was last updated July 30, 2008 at 6:05PM. </div>
WAI-ARIA provides for two dialog roles - dialog and alertdialog. When authors simulate dialogs on a web page they often limit their interaction considerations to the mouse. Unlike Graphical User Interface dialog boxes on a desktop computer, a user during keyboard navigation could accidentally navigate outside the dialog box and become disoriented. This can happen when the user is tabbing in the dialog. A modal dialog prevents the user from setting focus outside of the dialog until the dialog is closed. Mouse clicks outside of the dialog must be ignored and the user must not be able to tab into or out of the dialog itself. All WAI-ARIA enabled dialog boxes should be modal. This section describes how.
Mouse clicks outside of the dialog can be prevented by creating a CSS positioned element that is the size of the viewport to append as a child of the body element. Set the CSS z-index of this element so that it is above all other elements on the page except for the dialog element. Set the tabindex of the underlay element to tabindex="-1" to prevent it from receiving focus via a keyboard event or mouse click. You may lower the opacity of the underlay element in order to emphasize that the dialog itself is modal and has focus.
Depending upon the action to be performed by the dialog, the object with focus before the dialog box is opened should be saved. This will allow restoring focus to this element when the dialog box is closed. When the dialog box is opened, focus should be set to the first tab focusable element within the dialog. If there is no tab focusable element within the dialog box contents, set the focus to the item that is used to cancel or close the dialog. There must be some element within the dialog which can accept focus in order for the screen reader to speak the dialog title and information when it is opened. In order to prevent keyboard focus from leaving the dialog, determine the first and last tab focusable elements in the dialog and trap keyboard events within the document.
Search the contents of the dialog container to find the first and last tab focusable elements. This can be implemented by walking the DOM tree of the dialog container to find all visible and enabled anchor elements, input elements, and all elements that have a tabindex value greater than or equal to 0. Remember that elements with a tabindex > 0 will appear in the tab order before all other focusable elements in ascending order by tabindex. Store the first and last tab focusable items within variables in the scope of the dialog box code.
Before the dialog is shown, create and display the dialog underlay. Connect an onkeypress event handler to the DOM document.documentElement. This will catch all keystrokes on the document and allow trapping keyboard focus within the dialog. Size and position the dialog box in the viewport above the underlay, make it visible and set focus to the first tab focusable item in the dialog box.
The onkeypress handler will catch all key presses within the document. This onkeypress event handler should be within the scope of the dialog box code so that it has access to the first and last tab focusable elements within the dialog. In the onkeypress handler determine the target of the keypress event. In addition, determine if there is only a single focusable item within the dialog box. In this instance the first tab navigable object will equal the last tab navigable object. If key presses within the dialog box may create, destroy, enable, disable, or change the visibility of tab focusable elements, then determine the first and last tab-focusable items each time a keypress is received. Based on the event target and the key pressed take the following actions:
Determine if the target node of the keypress is within the dialog box container. This can be done using a while loop to walk the parent chain of the target node until the container node of the dialog box is found. Other than those outlined above, all key presses from within the dialog box should be allowed to execute so that the user can interact with the controls in the dialog box.
If the target node is not within the dialog box, the keypress is from the documentElement and the keypress event should be stopped unless it is a Tab key press. Allowing a Tab key press from the document element will enable tabbing back into the dialog box if, for some reason, focus on the dialog box is lost. This can happen due to timing issues when the dialog box is first loaded and focus does not properly get set to the first tab-focusable item within the dialog.
The dialog box itself should contain buttons or other mechanisms to cancel the dialog box or execute the dialog box functions and close the dialog box.
Here is a pseudo code onkeypress handler for a modal dialog box. Pseudo code is used to focus on the actions in the handler rather than on the differences in browser event handling. Assume that the event object, evt, has been normalized between browsers and the helper object is a library of functions that handle browser differences. The keys object is a set of key definition variables. Dialog is the dialog box object, which has a function to cancel the dialog.
_onKey: function(/*Normalized Event*/ evt){ // summary: // Handles the keyboard events for accessibility reasons if(evt.charOrCode){ var node = evt.target; // get the target node of the keypress event if (evt.charOrCode === keys.TAB){ // find the first and last tab focusable items in the hierarchy of the dialog container node // do this every time if the items may be added / removed from the the dialog may change visibility or state var focusItemsArray = helper.getFocusItems(dialogContainerNode); dialog.firstFocusItem = focusItemsArray[0]; dialog.lastFocusItem = focusItemsArray[focusItemsArray.length-1]; } // assumes firstFocusItem and lastFocusItem maintained by dialog object var singleFocusItem = (dialog.firstFocusItem == dialog.lastFocusItem); // see if we are shift-tabbing from first focusable item on dialog if(node == dialog.firstFocusItem && evt.shiftKey && evt.charOrCode === keys.TAB){ if(!singleFocusItem){ dialog.lastFocusItem.focus(); // send focus to last item in dialog } helper.stopEvent(evt); //stop the tab keypress event } // see if we are tabbing from the last focusable item else if(node == dialog.lastFocusItem && evt.charOrCode === keys.TAB && !evt.shiftKey){ if (!singleFocusItem){ dialog.firstFocusItem).focus(); // send focus to first item in dialog } helper.stopEvent(evt); //stop the tab keypress event } else{ // see if the key is for the dialog while(node){ if(node == dialogContainerNode){ // if this is the container node of the dialog if(evt.charOrCode == keys.ESCAPE){ // and the escape key was pressed dialog.cancel(); // cancel the dialog }else{ return; // just let it go } } node = node.parentNode; } // this key is for the document window if(evt.charOrCode !== keys.TAB){ // allow tabbing into the dialog helper.stopEvent(evt); //stop the event if not a tab keypress } } // end of if evt.charOrCode } // end of function
Marked up content or widgets will often need additional context to make clear what the meaning or purpose is. It is also reasonable that some content media types will need additional descriptions in another format to give clarity to those who are unable to consume the origin format. These additional meta-content sections are linked together by tagging them as labels or descriptions. WAI-ARIA provides the aria-labelledby
and aria-describedby
attributes to signal the browser to feed these relationships into the accessibility layer. This layer is then used by screen readers and other accessibility technology (AT) to gain awareness of how disparate regions are actually contextually connected to each other. With this awareness the AT can then present a meaningful navigation model for discovery and presentation of these additional content sections. The user agent itself can also choose to present these insights in a meaningful way. Generally you should always add these attributes to any widgets on your site as they are often merely a construct of HTML and JavaScript which provides no obvious insight as to what the widget's behavior or interactivity is.
aria-labelledby
by attribute. A label should provide the user with the essence of what the object does. For example, you could have a dialog box erected from HTML <div>
and you need to assocate a label for the dialog. With a WAI-ARIA role of dialog, you can indicate its widget type and define a label using an HTML header and then associate that label with the dialog using the aria-labelledby
relationship.
<div role="dialog" aria-labelledby="dialogheader"> <h2 id="dialogheader">Choose a File</h2> ... Dialog contents </div>
The section doing the labeling might be referenced by multiple widgets or objects as these need only reference the same id, so contextual description may not always be viable. The labelledby attribute can have multiple ids specified as a space separated list much like applying multiple classes to a single DOM object.
It should be noted that (X)HTML provides a <label for
> element which you can use to label form controls. For all visual objects, including (X)HTML form elements, you should use the WAI-ARIA aria-labelledby
property for labeling.
Some elements receive their label for embedded text content, but that is the exception.
When one element describes another, use the aria-describedby
attribute. An aria-describedby
section provides further information about a given object or widget, which may not be intuitively obvious from the context, content or other attributes. For example, a fake window is a common widget used in Web applications and is often constructed using a div absolute positioned in a layer above other content. To simulate common window behavior look and feel there is often an X box in the corner which, when activated, dismisses the window widget. One common way to make this X box is to simply make a link whose content is an X. This doesn't give a non-visual user much to go on and belies the real purpose of the X link. To help we add more descriptive text stored elsewhere in the page like this:
<button aria-label="Close" aria-describedby="descriptionClose" onclick="myDialog.close()">X</button>and then elsewhere in the HTML
<div id="descriptionClose">Closing this window will discard any information entered and return you back to the main page</div>Like labelledby, describedby can accept multiple ids to point to other regions of the page using a space separated list. It is also limited to ids for defining these sets. In our contrived example we would also want a good labelledby section to fully explain what the window does and how closing will effect the task being worked on. If an object or widget lacks describedby the user agent or AT may try to extract information from the label or th tags, if present. The label and th tags have limited use in that they can only be applied to forms or tables, respectively.
WAI-ARIA also defines the tooltip
role to which aria-describedby
may reference an author defined tooltip. The assistive technology can tell from the type of object describing the document element what the purpose of that element is. For example, a screen reader could announce the tooltip without the user having to waive the mouse over the element by following the describedby relationship to a document area with a tooltip
role. The aria-describedby
property is also useful for describing group
s.
Here is a code snippet showing a set of the tooltip:
... <div class="text"> <label for="first">First Name:</label> <input type="text" id="first" name="first" size="20" onfocus="tooltipShow(tooltip1)" onblur="tooltipHide(tooltip1)" onmouseover="tooltipShow(tooltip1)" onmouseout="tooltipHide(tooltip1)" aria-describedby="tp1" /> <div id="tp1" class="tooltip" role="tooltip">Your first name is optional</div> </div> ...
Two relationships expand the logical structure of a WAI-ARIA Web application. These are aria-owns
and aria-controls
. The aria-owns
relationship completes the parent/child relationship when it cannot be completely determined from the DOM created from the parsing of the markup. The aria-controls
relationship defines a cause-and-effect relationship so that assistive technologies may navigate to content effected by and changes to the content where the user is operating.
In addition to WAI-ARIA role and state information, for a document element,
an assistive technology needs to convey its context. In
the case of a treeitem
, it is important to know the parent (container),
which may provide a folder depth and the number of siblings in the folder. This containment hierarchy can often be determined by
the DOM tree, as it provides parent, siblings, and children for a given
document element. That said, the DOM hierarchy is rigid and acyclical in
that each node may only have one parent. In some situations, a child
is reused by multiple parents or a child is separated from its
sibilings or parent in the DOM tree. One example is when a radio button
appears in a table but it is not a DOM child of the radiogroup, due to the
authors use of a table for formatting and the placement of the radio buttons
placing them outside the radiogroup container. To solve this problem
WAI-ARIA provides the aria-owns
property.
The aria-owns
property is set on a document element, and its values are the
unique IDs of all the adopted children. These elements may appear anywhere
in the DOM, yet they are treated as siblings of each owning parent. This
example illustrates a radiogroup
that first uses the DOM hierarchy to
convey context and then aria-owns
:
First, consider the preferred method for using the W3C DOM to describe the relationship between
radiogroup
and radio
roles for HTML:
<div id="radio_label">My radio label</div> <ul role="radiogroup" aria-labelledby="radio_label"> <li role="radio">Item #1</li> <li role="radio">Item #2</li> <li role="radio">Item #3</li> </ul>
In this example, the elements with role="radio"
are child nodes of the parent role="radiogroup"
element node.
Now, consider an alternative method using the aria-owns
property to describe the parent-child
role relationship between radiogroup
and radio
roles for HTML:
<table> <tr> <td role="radiogroup" aria-owns="myradio1 myradio2 myradio3" rowspan="3" > My Radio Label </td> <td id="myradio1" role="radio">Item #1</td> </tr> <tr> <td id="myradio2" role="radio">Item #2</td> </tr> <tr> <td id="myradio3" role="radio">Item #3</td> </tr> </table>
The aria-owns
property should be used sparingly, since it
increases the computational load on assistive technology to provide
alternative renderings. Also, when accessing the DOM and enumerating
children of a DOM node, an AT should then enumerate the adopted children
using the aria-owns
property. At that instance of walking the DOM, the
parent of the adopted children is the adopted parent and not the DOM
parent. This will avoid recursion problems.
Each child, adopted or natural, should have the appropriate
aria-posinset
and aria-setsize
properties set consistent with their
rendering, if these cannot be determined from the DOM from a direct parsing of
the host language. Places where direct parsing does not allow the user
agent to determine
aria-posinset
and aria-setsize
are long lists where only
the currently visible items are loaded (via Ajax). If the children are
re-sorted then the
aria-posinset
and aria-setsize
values should be updated
consistent with their visual rendering. Rather than setting size only on a container, content authors should specify aria-setsize on each member of a set to avoid performance issues. If this property is not set, the user agent must compute and set the property on supporting roles.
Platform accessibility API mappings must invert this relationship for
assistive technologies, so that they may determine the owning parent from a
child and couple it with aria-posinset
and aria-setsize
information to
provide context information to the user.
If you are re-using content across different, transient sections of content by restyling it to render it in association with a different object, you need to maintain the aria-owns
property as well to match the current use and apparent ancestry of the reused sub-section. A good example of this is a context help menu that resides at the end of the document. When the user wishes to launch the context help menu in association with different visual elements, styling is used to render the menu in context with that object. Prior to rendering the visual submenu you should ensure the object to which you have requested help assigns its aria-owns
property value to the submenu ID. When the menu closes you can remove the aria-owns
property.
In rich internet applications document elements may control the behavior on another part of Web page outside themselves. The aria-controls
attribute indicates cause-and-effect relationships between document elements.
An example might be a group of radio
buttons that "control" contents of a listbox
in another part of the page. Here, you would want the radio group to assign a aria-controls
relationship to the listbox
which will be updating without a page reload. The user, through their assistive technology, can then navigate to the listbox
by following the aria-controls
relationship when a different radio is selected, to see how the contents changed in the listbox
. The ability to update parts of a page without a page reload is a common practice of applications making use of Ajax. Without the aria-controls
attribute, a user would be unable to effectively use these types of Web pages as assistive technologies often will not make the user aware of what is happening outside the context of the element the user is currently operating.
With the aria-controls
attribute the user may use the assistive technology to follow the relationship to the object it is controlling. It is extremely important for an assistive technology to present changes in the document in response to user input. Therefore, an assistive technology immediately presents changes to a live region when the controlling widget is the one which has user keyboard focus. For example, if a tree view controls a help document pane, each time
the tree item changes the new tree item and then the new help contents should also be read. In the case of a screen reader, the amount of information read in the target live region is dependent on how the live region is configured.
The aria-controls
attribute takes one or more ids which refer to the document element. If this relationship is not implied by the host language semantics, then the controlling element must be given a controls attribute with the IDs of the other elements where the changes will show up listed in the attribute value.
(X)HTML suffers from a number of disadvantages in keyboard navigation today. One such example is the restriction of navigation to the tabbing order. This is a common problem with presentations in office suites where the logical, perceivable, navigation order of a slide may not match the tabbing order. Sighted users may see a logical navigation process (such as visual steps in the process for assembling a lawn mower). This "flow" is not conveyed by the tab order. The user might tab from step 1 and land on step 4. Another problem is the construction of model-based authoring tools on a Web page. In a model-based authoring tool, a visual object may provide a number of paths that the user can take, such as a multiplexor, which may have output that logically flows to a number of optional electronic components in a drawing. In Web 2.0, developers are actually creating drawings like this to perform tasks such as visually model a work flow. In this scenario, the user will want to decide which object they will navigate their screen reader or alternate input device to next.
Although it is recommended that Tab order follow the reading flow, there may be instances where this is not possible. For these reasons, WAI-ARIA provides a relationship property, called aria-flowto
. This allows the author to provide an assistive technology with alternative navigation flows through the document that best represents the author's intent and which is more logical for people with disabilities. aria-flowto
establishes the recommended reading order of content, so that the an assistive may overriding the default of reading in document order to its user. aria-flowto
does not change the keyboard navigation order of they browser.
Consider the first case of changing a basic reading flow to circumvent(X)HTML tabbing. A good example of this is a logical reading flow in a portal with landmarks. In the future, the user may wish to change the reading flow based on the order of priority with which they navigate a personalized Web application like MySpace or MyYahoo. In the following example, the navigation would follow the order of "Top News Stories", "television listings", "stock quotes", and "messages from friends" by following (X)HTML document reading order. However, the author or end user may determine that the main content is most important, followed by "stock quotes", "messages from friends", and then "TV listings."
<html> ... <div role="main" title="Top News Stories" id="main" aria-flowto="stock"></div> <div role="complementary" title="television listings" id="tv"></div> <div role="complementary" title="stock quotes" id="stock" aria-flowto="messages"></div> <div role="complementary" title="messages from friends" id="messages" aria-flowto="tv"></div>
The second use case is such that the Web developer may wish to circumvent the flow by branching to multiple paths in the Web page, requiring the assistive technology to present a collection of options where the user could go next. This is important for work flows or business process management applications as shown in this Process Designer Tool. More of these applications are becoming Web based, and a vehicle is required to tell the user how to get through the work flow. The flowto property takes multiple idrefs, allowing the author to define each object the user could flow to. To implement this technique do the following.
Make each object in the work flow accessible
This will require assigning a title or WAI-ARIA label for each object and a unique HTML id. Also, if the html element is repurposed assign it a WAI-ARIA role.
<html> ... <img src="foo.jpg" id="331" title="What is the Invoice Value?"> <img src="foo.jpg" id="333" title="Finance Manager Approval"> <img src="foo.jpg" id="334" title="Sales Manager Approval"> ...
For each visual object that will flow to one or more other objects assign the flowto property the list of IDs to which it flows.
<html> ... <img src="foo.jpg" id="331" title="What is the Invoice Value?" aria-flowto="333 334"> <img src="foo.jpg" id="333" title="Finance Manager Approval"> <img src="foo.jpg" id="334" title="Sales Manager Approval"> ...
Each element referenced by the flowto must have have a unique id. The combination of the unique id and the name allow the assistive technology to adequately assist the user in retracing their steps backward through a flow to reference or moving forward to it. Since the author sets only the target the user agent is responsible for mapping the backward reference relationship. Therefore, neither the user agent nor the user can get lost. The host user agent does not provide an alternative navigation order; this is an assistive technology function.
Use tabindex to enable objects to receive focus. Actually setting focus to them may be performed by an assistive technology, such as an alternative input device. This example places each drawing object in document order with respect to the tab sequence.
<img src="foo.jpg" id="331" title="What is the Invoice Value?" aria-flowto="333 334" tabindex="0"> <img src="foo.jpg" id="333" title="Finance Manager Approval" tabindex="0"> <img src="foo.jpg" id="334" title="Sales Manager Approval" tabindex="0"> ...
When an assistive technology encounters "What is the Invoice Value?," it will know to tell the user that they may choose to navigate either to the "Financial Manager Approval" or to the "Sales Manager Approval" object. The options may be provided through a menu for the What is the Invoice Value object by the assistive technology. After a choice is made, then the AT can move focus to the target object; or in the case of a screen reader, it may just move the user to that location in the screen reader's virtual buffer.
Note: WAI-ARIA does not specify backward flowto properties for the same reason that we do not have the reverse of relationships like labelledby. The author may incorrectly do the reversal, creating a whole set of new problems. Rather, the task of the reversal relationships may be handled by the user agent through its accessibility API mapping or in the assistive technology itself.
In order for menus, menubars, and menuitems to indicate that it opens a menu, set its aria-haspopup
property to "true." The type of menu being launched (submenu, context help, etc.) is not explicitly indicated with WAI-ARIA but is based on the operational characteristics (keyboard and mouse commands).
Combo boxes, or drop down lists, work differently. Controls with the role combobox
must contain a list of items that can be opened, usually as a drop-down. Because this is intrinsic to the functioanlity of a combo box, it does not need to be explicitly indicated with aria-haspopup
.
General rules for managing content and displaying information
display
property to WAI-ARIA hidden state. This is important for assistive technologies who communicate directly with the user agent's DOM versus a platform accessibility API supported by the user agent. You can also tie CSS visibility:hidden
or visibility:collapse
to the WAI-ARIA hidden state but the use of visibility:hidden
will affect layout in that content will continue to flow around the hidden area even though the content to be hidden is invisible. If you are refreshing areas asynchronously, then you need to designate live regions. The following sections explain how to implement live regions and when to use roles that are considered "live" sections by default, including alert, status, or log.
Live regions are parts of a Web page that the author expects to change. Examples of live regions include tables with dynamically updated content (sports stats, stock information), logs where new information is being added (chat transcript logs), notification areas (status, alerts), etc.
Live regions enable assistive technologies, such as screen readers, to be informed of updates without losing the users' place in the content. Live region settings provide hints to assistive technologies about how to process updates. Note that the assistive technology is responsible for handling these updates and enabling users to override these hints.
The section on Live Region Properties and how to use them gives the details of how to apply live region properties. This process will help rich internet application (RIA) developers to set live region settings that will provide a good user experience for most assistive technology users with little configuration on their part. When applying these live region properties, it is recommended that you conduct user testing. If the AT supports scripting of the response to live regions you may wish to customize the response, such as through a screen reader script for your Web page.
Identify the live regions
Live regions are any region on a page that receives dynamic updates through client-side scripting. Note the regions of your page that will be live.
See if any of the special case live regions meet your needs
WAI-ARIA provides a number of special case live region roles whose live region properties are pre-defined and which you may use. If one of these live region roles meet your needs just apply the specific role to the region of the Web page.
Decide the priority of each live region
When a live region changes, should the user be notified of the change? Notifications could include a sound for a screen reader user. (For simplicity, we will use the case of an audio notification in this discussion.) The shorter the interval between changes and the less important the information, the less likely that the user needs to hear every change. A simple example of changes that should not be heard are changes to time; a sound for every second would be very annoying.
If the user should hear the change, should the change be announced immediately, as soon as possible, or only when the user is idle? Announcing a change immediately can be disorienting for users, so that should be done sparingly. Most updates should probably only be announced when the user is idle.
After you have decided the priority for each live region, then decide the live property value:
aria-live
="off"
aria-live
="polite"
aria-live
="assertive"
Decide how much context is needed for each update
When part of a live region changes, how much context is needed to understand the change. Does the user need to hear the entire live region or just the change by itself?
If the user needs to hear the entire live region, then mark the entire live region with aria-atomic
="true".
Decide what types of changes are relevant for each live region
Three possible types of changes are: additions, removals, and text. Additions means new nodes are added to the DOM; removals means nodes are removed from the DOM; and text means changes are solely to the textual content. Should the user hear all types of changes or only certain types?
By default, the user will hear additions and text type changes. If you wish to explicitly define the types of changes, you need to set relevant="THE_TYPES_OF_CHANGES". If more than one type of change is relevant, the types are separated by a space. For example, to define additions and removals as relevant but not text, set relevant="additions removals".
One of the most important concepts behind live regions is politeness. Politeness indicates how much priority a live region has. The following politeness values are available for aria-live
: off, polite, and assertive.
aria-live
="off"aria-live
="polite"aria-live
="assertive"There are times to suppress AT presentation changes while a region is updating. For that you can use the aria-busy
(state) property.
aria-busy
(state)="true"To suppress presentation of changes until a region is finished updating or until a number of rapid-fire changes are finished, set aria-busy
(state)="true" and then clear the attribute when the region is finished. While it is busy, the AT will track and collate the changes. It will finally speak the changes once the region is no longer busy.
When a live region is updated, the update can often be announced on its own and still make sense. For example, if a news headline is added, it would make sense to simply announce the headline. However, sometimes the entire live region must be read in order to give the user enough context to make sense of the update. For example, it would not make sense to only give the current value of a stock without saying the name of the stock. The atomic setting gives assistive technologies a hint about which of these cases an update falls into.
aria-atomic
="false"aria-atomic
="true"aria-relevant
="additions"aria-relevant
="removals"aria-relevant="removals"
or aria-relevant="all"
should be used sparingly. Notification of an assistive technology when content is removed may cause an unwarranted number of changes to be notified to the user. aria-relevant
="text"This example shows two live regions. If both regions update simultaneously, liveRegionA should be spoken first because its message has a higher priority than liveRegionB.
<div id="liveRegionA" aria-live="assertive"> </div> <div id="liveRegionB" aria-live="polite> </div>
You may wish to use a special live region role instead of applying live region properties. WAI-ARIA contains a number of standard roles which are by default considered "live" sections of your Web page. It is important to know when to use these and when to create a custom live region on your known. Here are some rules of thumb:
alert
- You must use thealert
role for a one-time notification which shows for a period of time and goes away and is intended to alert the user that something has happened. The assistive technology should be notified by the user agent that an alert has occurred, if your operating system supports this type of event notification. When choosing to use alert you should use thealertdialog
role instead if something inside the alert is to receive focus. Bothalert
andalertdialog
appear to pop-up to the user to get their attention.
status
- You must use thestatus
role when you want to mark an area which is updated periodically and provides general status of your Web application. Changes in status are not typically announced automatically by an assistive technology. However, it is possible to configure some assistive technologies, such as a scriptable screen reader, to watch for changes in the status bar and announce them. Using the status role is also important in that the user could always check the status section for changes in status on different Web pages. Many applications provide status widgets and they are often found, visibly, at the bottom of the application and contain a variety of widgets within it to convey status. The use ofstatus
does not guarantee how the AT will respond to changes in the status. The author can still put live="off" or live="assertive" to influence the ATs treatment of the status.
timer
- You must use a timer role when you want to mark an area which indicates an amount of elapsed time from a start point, or the time remaining until an end point. The text encapsulated within the timer indicates the current time measurement, and are updated as that amount changes. However, the timer value is not necessarily machine parsable. The text contents MUST be updated at fixed intervals, except when the timer is paused or reaches an end-point.
marquee
- You must use a marquee role when you need to mark an area with scrolling text such as a stock ticker. The latest text of the scrolled area must be available in the DOM. A marquee behaves like a live region, with an assumed defaultaria-live
property value of "polite."
log
- You must use log if you have a live area where new information is added, like a scrolling chat log of text. Unlike other regions, implied semantics indicate the arrival of new items and the reading order. The log contains a meaningful sequence and new information is added only to the end of the log, not at arbitrary points. If you have a chat text entry area you should indicate that it also controls the aria log aria like so:<div contenteditable="true" role="log" id="chatlog"> </div> <label id="gettext">Send Text</label> <div aria-controls="chatlog" role="textbox" contenteditable="true" aria-labelledby="gettext"> </divlive region - If you have some other live area use case, WAI-ARIA allows you to mark an area using the
aria-live
attribute. This accompanied by the collection of attributes which support the live property allow you to create your own custom live area on your Web page. For more details regarding live regions refer to the live region section of the this guide.
This section identifies authoring practices for elements used as form elements.
Until the introduction of WAI-ARIA's aria-invalid state and aria-required property, only presentational strategies have been available to Web content authors to indicate that certain form fields and controls are required or invalid. In applications, these states are only available through styling or varying markup, which is inconsistent, and therefore is inconclusive. In Web-based forms, fields required may be marked by an asterisk. Forms submitted with required data missing or improperly specified may be redisplayed with the unacceptable elements highlighted in red. The assistive technology user is poorly served by such imprecise methods, and all users confront inconsistent indicators for consistent situations.
The WAI-ARIA invalid state and required property provide:
When a text input field that has a maximum length value (or the host markup language's equivalent) receives focus, the value defined for "maximum length" should be communicated to the user. When text entry reaches that maximum length (or the markup language's equivalent), an alert (expressed in accordance with user preferences and capabilities) should inform the user that the maximum length for a given field has been reached. Such an alert can be expressed programmatically or, using as an aural icon, by using a WAI-ARIA alert; the user agent may alert the user through a system beep and by triggering the operating systems' "show sounds" facility. When maximum length (or the markup language's equivalent) is reached, the user must then be able to move to another form field in a manner consistent with tab-navigation for that document.
Having a user agent automatically change focus in a form in response to user input can be advantageous in situations where that change saves the user keystrokes or on-screen keyboard interaction in order to manually move the focus from one field to another. However, as with form auto-completion, this type of text input event must be firmly under user control because this may not have been the user's intention and some users with disabilities may become disoriented such as those with sight impairments. Consider these cases:
Use caution when using automatic submission of a form without explicit user command or in response to a user-defined setting that permits such behavior, as expressed by the Priority 1 UAAG 1.0 Checkpoints 7.1, 7.2 and 11.1. Unless the user has specifically chosen to set the user agent to allow auto-submission, authors are advised not to set onChange or onFocus events either to trigger submission of a form or to provide an auto-submission event upon completion of all or all required fields of a form or input field.
Drag-and-drop operations are a common feature of Rich Internet Applications (RIAs). Drag-and-drop features have traditionally challenged people with functional disabilities. These problems arise from the difficulty of manipulating the mouse, finding targets capable of receiving the object being dragged, and actually moving the object to the drop target. Screen readers and alternate input systems assist the user to some degree by allowing the user to simulate a click, drag, and release operation. It is then up to the user to find a target that, hopefully, will receive the object(s) being dragged. Additionally, the user may not be aware if the desired drop operation is supported or what source objects can be selected for dragging. The end result can be a very unproductive and frustrating experience.
WAI-ARIA introduces two new Drag and Drop properties that aide Web application authors with the drag and drop process, called aria-grabbed and aria-dropeffect. The property aria-grabbed
(state) is applied to the source(s) being dragged, while aria-dropeffect
is applied to the target(s). Use of these properties--combined with best practices for enabling the user to select the appropriate drag operations and for assigning appropriate keyboard operations for dragging and dropping--will vastly improve the accessibility of drag and drop functionality. The following steps will guide you through the process.
Identify draggable objects
Set the initial aria-grabbed
(state) state of all draggable interface objects.
Roles that typically support drag and drop operations are listitem
and treeitem
. The default state for all objects is assumed to be undefined, meaning that they are not draggable. For objects that may be dragged, set the aria-grabbed
(state) state to "false". This will allow assistive technologies to indicate which objects are draggable and potentially facilitate in choosing the objects to grab.
Objects that can be dragged need to have a determinable role. HTML tags such as <div>
and <span>
provide no semantics, unlike <select>
, and would require you to set the WAI ARIA role attribute.
This step clearly marks elements that can be "grabbed" for drag-and-drop operation. Assistive technologies, such as screen readers or alternate input devices, can help the user move focus directly to the grab-supporting objects without having to navigate through all the elements and to guess which could be ready to initiate a drag operation. Although not necessary, authors or intermediaries could use CSS to highlight those elements that may be grabbed. At this point, qualified drop targets cannot be determined as they are determined based on the objects being dragged--which have not yet been selected.
All grabbable objects must be navigable using the keyboard.
Allow the user to initiate the appropriate drag operation using the keyboard
The author must provide a keyboard accessible way of selecting one or
more elements to drag. It is recommended that the space bar be used for
selection. It is further recommended that Shift+Space be used to select
multiple objects and define a contiguous set; and that control+space be
used to define a noncontiguous set. As each object is selected, its
aria-grabbed
(state) property must be set to "true", giving the ATs references as
to what has been grabbed. It is recommended that Ctrl+M be supported
to indicate that all objects have been selected for drag.
Note: Selection of the objects to be dragged may differ depending on their type. For example, a list of emails might be selected one at a time or many at a time in contiguous or non-contiguous manner using the Space key as indicated above. However, text in a document might better be selected by positioning the cursor at the beginning of a word and holding down the Ctrl key while using the right and left arrow keys to mark the letters you wish to move.
Mark the drop targets
When the user has completed selecting source objects to drag, you must indicate which targets may receive them by setting the aria-dropeffect
properties on those targets. This will indicate to the assistive technology that all objects have been grabbed as well as what targets are capable of receiving the drop.
When using a mouse, users click, hold the mouse button, and drag the mouse when moving the selected objects, and, by implication, are no longer selecting them. With respect to keyboard users, the previous section, Item 2, "Allow the user to initiate the appropriate drag operation using the keyboard", recommends using Control+M to indicate the end of the selection phase.
Example:
<div role="treeitem" aria-dropeffect="copy move popup">
CSS may also be used to highlight the targets to show sighted users
which objects can receive a drop of the grabbed source(s). Any object
without an aria-dropeffect
property set will have an assumed
aria-dropeffect value of "none." Any object with an aria-dropeffect
value
of "none" is ignored by ATs in the drop operation.
Implement keyboard functionality to assist the user and AT with executing the drop.
After all objects have been grabbed, the author should provide standard keyboard accessible navigation (such as through tabbing) to enable the user to navigate to the desired drop target. To achieve this, you may optionally support Shift+F10 to invoke a single select list of possible drop targets from which the user may choose a single drop target that, when selected, would move focus to that drop target. Otherwise, you must provide a keyboard accessible way (through tabbing and arrowing) to allow the user to navigate to the drop target. The user's point of regard should be clearly visible during this navigation.
When the user arrives at the drop target the author should provide a keyboard accessible way to drop the selected object(s) onto the target. Ctrl+M should be used to provide the most intuitive type of drop, either copy, move, or a shortcut. In the case of only one drop operation available, the Ctrl+M should be used to drop the selected object(s) onto the target.
If drop target supports additional drop operations, then the
author should provide a WAI-ARIA-enabled pop-up menu from which the user
can choose supported operations from the list. A recommended way to
invoke this menu is to use the Shift+Ctrl+M key sequence when focus
is on the drop target. Furthermore, the aria-dropeffect
property should include "popup" in its list of values to indicate that a
keyboard accessible menu is provided. After the user has selected an
action from the pop-up menu, the menu must close, with focus returning
to the drop target. If the user does not choose an action and instead
presses the Esc key, the application must dismiss the menu,
returning focus to the drop target.
Cancelling a drag operation
If at any time during the drag process the user presses the Esc key to cancel drag operations, all aria-dropeffect
properties must be set to "none", keyboard focus should return to the last grabbed source object, and all grabbable objects' aria-grabbed
(state) properties must be set to "supported."
Clean-up after drag/drop
Once the drop has occurred, you should clean up the DOM as you would do for drag-and-drop operation. This should include setting:
aria-dropeffect
properties to "none" or remove them altogether.aria-grabbed
of draggable objects to "false".aria-grabbed
property or have an aria-grabbed
property set to "undefined."Other methods of performing the same operation as drag-and-drop may be the best way to meet the accessibility requirements. As an example, when moving a mail message from the inbox to another folder, a list of those folders could be presented in a select list as an alternative to drag-and-drop.
Document non-recommended keyboard navigation
If the author must use alternatives to the keyboard navigation recommended here, it should be documented on the page.
States and Properties that an Assistive Technology is likely to change:
Authors should monitor changes to these properties by monitoring <a href="http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-MutationEvent">DOM Mutation events</a> for attribute changes and respond accordingly by making the appropriate changes to your web application. Note that if any of these states and properties are set in error, the Web application is responsible for handling the error condition.
The following States and Properties are unlikely to be manipulated by an assistive technology: An AT would need to have greater understanding of the application and the results could be adverse.
For these widgets and structures, this document describes the keyboard interaction and identifies the relevant WAI-ARIA roles, states, and properties.
If the host language does not define key mappings, such as hot keys, and the author defines key mappings other than those described here or in Drag-and-Drop Support, then the author must provide documentation of those key mappings. These mappings can be provided in the contents of the web page, or in the case of a more complex application, within the help file documentation and training materials.
Note: Although users of Mac OS X are familiar with using the Command key (Cmd) instead of the Control key (Ctrl), the Command key is typically reserved for desktop applications and OS-level integration. Until device and platform independence can be addressed in ARIA 2.0, the primary "Control" modifier key for WAI-ARIA widget interaction is specified as "Control" on all platforms, including Mac OS X.
The following may apply to some or all widgets.
Rich internet applications are complex to author. To save time, it is often faster to use existing widget libraries that implement WAI-ARIA and that have already gone through:
Some publicly available UI component libraries have already implemented WAI-ARIA. Authors can reuse such libraries to start developing accessible rich internet applications.
The following people contributed to the development of this document.
Special thanks to Aaron Leventhal for effort and insight as he implemented a working prototype of accessibility API bindings. Special thanks to Al Gilman for his work while chair of the PFWG in bringing the ARIA technology to fruition.
Simon Bates, Chris Blouch (AOL), Judy Brewer (W3C/MIT), Christian Cohrs, Donald Evans (AOL), Becky Gibson (IBM), Alfred S. Gilman, Andres Gonzalez (Adobe), Jeff Grimes (Oracle), Barbara Hartel, Earl Johnson (Sun), Jael Kurz, Aaron Leventhal (IBM Corporation), Alex Li (SAP), Linda Mao (Microsoft), Shane McCarron (ApTest), Lisa Pappas (Society for Technical Communication (STC)), Dave Pawson (RNIB), Marc Silbey (Microsoft Corporation), Henri Sivonen (Mozilla), Vitaly Sourikov, Mike Squillace (IBM), Ryan Williams (Oracle), Tom Wlodkowski.
This publication has been funded in part with Federal funds from the U.S. Department of Education, National Institute on Disability and Rehabilitation Research (NIDRR) under contract number ED05CO0039. The content of this publication does not necessarily reflect the views or policies of the U.S. Department of Education, nor does mention of trade names, commercial products, or organizations imply endorsement by the U.S. Government.