[contents]

W3C

WAI-ARIA 1.0 User Agent Implementation Guide

W3C Working Draft 24 February 2009

This version:
http://www.w3.org/TR/2009/WD-wai-aria-implementation-20090224/
Latest version:
http://www.w3.org/TR/wai-aria-implementation/
Editors:
Aaron Leventhal, IBM
Michael Cooper, W3C

Abstract

This document describes how user agents should respond to roles, states, and properties provided in Web content via WAI-ARIA [ARIA]. These features are used by authors creating accessible rich internet applications. Users often access the content using assistive technologies that rely on platform accessibility APIs to obtain and interact with information from the page. The WAI-ARIA User Agent Implementation Guide defines how implementations should expose content to accessibility APIs, helping to ensure that this information appears in a manner consistent with author intent. This document is part of the WAI-ARIA suite described in the ARIA Overview.

Status of this Document

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 document is a First 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 information about how user agents should expose ARIA features to platform accessibility APIs. Implementers of mainstream user agents that work in concert with third party assistive technologies should follow the approaches in this document.

The Protocols and Formats Working Group has not yet decided whether the advice in this document should ultimately be normative, meaning user agents that conform to ARIA must conform to this document, or informative, meaning it provides advice that user agents should follow for interoperability, but may deviate from the advice when there is reason. At present, this document is not on the W3C Recommendation Track and is expected to become a Working Group Note.

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:

Comments on this document may be sent to public-pfwg-comments@w3.org (Archive). Comments should be made by 24 March 2009, although comments arriving later may still be considered. 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.

Table of Contents

  1. 1. Introduction
    1. 1.1. Accessibility APIs
    2. 1.2. Accessible tree vs. DOM tree - what's the relation?
  2. 2. Supporting Keyboard Navigation
    1. 2.1. Controlling focus with tabindex
    2. 2.2. Controlling focus with ARIA
    3. 2.3. Handling focus changes from the AT
  3. 3. Mapping ARIA to APIs
    1. 3.1. General rules for exposing ARIA semantics
    2. 3.2. Conflicts between native markup semantics and ARIA
    3. 3.3. Exposing attributes that don’t directly map to accessibility API properties
    4. 3.4. Role mapping
    5. 3.5. State and Property Mapping
    6. 3.6. Special Processing Requiring Additional Computation
      1. 3.6.1. Name and Description
      2. 3.6.2. Widget Values
      3. 3.6.3. Relations
      4. 3.6.4. Group Position
  4. 4. Managed States
    1. 4.1. Exposing Supplemental Interfaces
    2. 4.2. Actions
    3. 4.3. Changes to document content or node visibility
    4. 4.4. Selection
    5. 4.5. Menus in MSAA/IAccessible2
  5. 5. Special Document Handling Procedures
    1. 5.1. Documents, Handling frame and iframe elements
    2. 5.2. CSS Selectors
  6. 6. Error Handling
    1. 6.1. Definitions
    2. 6.2. Value type: IDREF and IDREFS
    3. 6.3. Value type: decimal
    4. 6.4. UA Validation
    5. 6.5. Roles
    6. 6.6. States and Properties 
    7. 6.7. Propagating errors to ATs
  7. 7. Appendices
    1. 7.1. References
    2. 7.2. Acknowledgments
      1. 7.2.1. Participants in the PFWG at the time of publication
      2. 7.2.2. Other previously active PFWG participants and other contributors to the Accessible Rich Internet Applications specification
      3. 7.2.3. Enabling funders

1. Introduction

If a user agent already exposes static content via the accessibility API on a given platform, most of the remaining work to enable ARIA can be divided into three parts:

  1. Making focus and tab navigation work on elements that previously were not focusable
  2. Mapping the ARIA roles and properties into the roles, states and other property getters in the accessibility API on a given platform
  3. Computing managed states and events, which are calculated from a mix of internal information

In general, ARIA properties should only affect how content is mapped to platform accessibility APIs. It should not affect the visual rendering of content or the behavior of mainstream desktop browsers, except when style sheets are deliberately keyed off of ARIA attributes as recommended in the specification. This allows one of the primary principles of ARIA to be upheld—that content still renders and behaves the same for the majority of users in legacy browsers which do not support ARIA.

1.1. Accessibility APIs

Accessibility APIs covered by this document are:

Information on how to best expose ARIA to the Mac OS X Accessibility Protocol, UI Automation, or other accessibility APIs is not yet available, but would be appreciated, as would any other feedback on the information contained in this document. If you need to expose to other accessibility APIs, it is recommended closely with assistive technology developers.

1.2. Accessible tree vs. DOM tree - what's the relation?

The accessible tree and the DOM tree are parallel structures. Roughly speaking the accessible tree is a subset of the DOM tree. Accessible objects are created in the accessible tree for every DOM element that should be exposed to an assistive technology, either because it may fire an accessible event or because it has a property, relationship or feature which needs to be exposed. Generally if something can be trimmed out it will be, for reasons of performance and simplicity. For example, a <span> with just a style change and no semantics will not get its own accessible object, but the style change will be exposed through a "text attribute run" in the AccessibleText interface.

In addition to the normal accessible tree, ARIA requires that the elements also be exposed if they have one of the following properties:

Objects that should be removed from the accessible hierarchy (including their descendants):

When descendant trimming occurs, the Accessible Hypertext interface should also not be exposed for the root object that remains. The descendants are removed because their presence confuses some assistive technologies that do not expect descendants for these roles (e.g. the JAWS virtual buffer would speak the accessible name twice or reveal the slider thumb as an image).

Document conventions

Note: in the following sections, Boolean states from IAccessible2 and ATK are marked in all-caps, e.g. FOCUSABLE.

2. Supporting Keyboard Navigation

Enabling keyboard navigation in web applications is the first step toward making accessible web applications possible. There are two mechanisms that allow for accessible script widgets: tabindex and aria-activedescendant. Most other aspects of ARIA widget development depend on keyboard navigation functioning properly.

Assistive technologies often need to set the focus. For example, voice input software, onscreen keyboards and screen readers supply their own structured navigation modes, providing additional commands for moving to elements in a page. Both the user agent and web pages need to handle this gracefully. Script container widgets cannot expect that focus changes occur only from the keyboard or a mouse click. They need to listen for focus or aria-activedescendant changes and update their state when that occurs.

2.1. Controlling focus with tabindex

User agents that support ARIA expand the usage of tabindex, focus, and blur to allow them on all HTML elements. The HTML 5 Working Draft adopts this practice, so this usage is expected to be per specification in the next version of HTML.

In HTML 4 and earlier, only links and form controls participated in the tab order and could receive focus. It was not possible to set focus to other elements, even using script focus methods. While it was possible to include such elements in the tab order with tabindex, it was not possible to make them focusable but not in the tab order. To work around this problem, user agents expand the scope and allowed values of the tabindex attribute.

Essentially, any element such as a div, span or img can be added to the default tab order by setting tabindex="0". In addition, any item with tabindex="-1" can be focused via script or a mouse click, but isn't part of the default tab order.

The tabindex system provides one way to develop custom widgets which are keyboard accessible, from simple widgets like a slider to container widgets like a menubar, tree view or spreadsheet. This system works in older versions of Internet Explorer, as far back as IE 5.5.

The user agent implementation must to do the following to enable tabindex on all elements:

  1. Every element can be a) not focusable (nor tabbable), b) focusable but not tabbable, or c) both focusable and tabbable. The presence and value of the tabindex attribute must affect this, even on traditionally non-focusable elements. Mouse click handling and tab navigation code in the user agent must utilize this information.
  2. Every HTMLElement must expose the element.tabIndex property.
  3. The focus and blur methods should be added to the HTMLElement interface (available to script for every type of element).
  4. Any element that can receive focus must fire focus and blur events.
  5. The default style sheet must include rules so that any element with :focus receives a focus outline.
  6. Canceling a keydown event must also cancel the keypress event, for purposes of compatibility with other browsers. This is necessary because authors supporting Internet Explorer must use keydown events to process keystrokes, where keydown but not keypress events are fired for non-alphanumeric keys. As web page authors implement script control over the keyboard they need to be able to use keydown but cancel the effect of consumed keystrokes such as arrow keys.
  7. Ensure that all elements which are focusable are exposed in the accessible object hierarchy, so that when they get focused there is an object to fire an accessibility event for.
  8. Expose the FOCUSED and FOCUSABLE accessibility API states, and focus accessibility API event for any element in the accessibility hierarchy, where appropriate.
  9. In some cases, Enter on a focused element should act like a click ([HTML5], Section 3.4.1.7).

The HTML 5 spec documents what the extended behavior of tabindex should be ([HTML5], Section 6.5.1). The Gecko documentation on what the behavior should be is in Key-navigable custom DHTML widgets. The documentation for IE's tabindex behavior is in MSDN: tabindex Property. Opera has some simple testcases.

2.2. Controlling focus with ARIA

The aria-activedescendant property could also be used to enable keyboard accessibility on any type of ARIA element. It is often a more convenient way of creating container widget keyboard navigation (where the entire widget is in the tab order just once, but the user can use keystrokes to navigate to descendant items of the container).

Typical usage is described as follows: the author will use tabindex="0" on the container element and aria-activedescendant to point to the ID of the currently active descendant. The author, not the user agent, is responsible for styling the currently active descendant to show it has keyboard focus (not via :focus since actual focus is on the container).

The user agent must do the following to implement aria-activedescendant:

  1. Implement the tabindex recommendations from HTML 5 Tabindex. Support for tabindex="0" on all elements is still necessary for authors to use aria-activedescendant system, because the container widget must be in the tab order.
  2. For an element that has focus in the DOM, but also has aria-activedescendant which points to a valid ID, do not mark it as focused in the accessibility API (iow don't use the states FOCUSED or FOCUSABLE)
  3. When the aria-activedescendant attribute changes on an element that currently has DOM focus, fire an accessibility API FOCUS event on the new active descendant. If aria-activedescendant is cleared or doesn't point to an element in the current document, then fire a focus event for the container object that had the attribute change.
  4. For any element with an ID attribute, where the element is a descendant of an element with the aria-activedescendant attribute, apply the following states to the target to ensure the object is accessible:
    1. FOCUSABLE, if the element also has an ARIA role—because the aria-activedescendant of the container can potentially point to it. It is not absolutely necessary to check this when there is no role, because real HTML elements that would be focused would already be focusable.
    2. ACTIVE, whenever the container element sets aria-activedescendant to match the ID of this descendant
    3. FOCUSED, if ACTIVE and the container widget with aria-activedescendant has true DOM focus
  5. If the AT sets focus to a descendant of a container with aria-activedescendant, the implementation should change the value of aria-activedescendant to point to that item.

Note for authors: as you move focus to the next descendant, ensure that it is scrolled into view using scrollIntoView()([HTML5], Section 6.4).

2.3. Handling focus changes from the AT

Alternative input software needs to be able to set focus to items exposed as FOCUSABLE. Screen readers, voice input software and on screen keyboards may set focus based on user commands implemented in that software. An MSAA-based AT does this via accSelect(SELFLAG_TAKEFOCUS) and in ATK this comes via AtkComponent::grab_focus.

Note for authors: you will need an onfocus handler to enable alternative input. For example, when implementing a listbox with focusable list items, don't assume that a mouse click or key press are the only ways a new list item may receive focus. Therefore, any direct style changes to the focused element should happen in the onfocus handler instead of the click and keypress handlers. For the same reason, when using aria-activedescendant, watch for DOMAttrModifed (onpropertychange in IE) to react to changes to these attributes.

3. Mapping ARIA to APIs

3.1. General rules for exposing ARIA semantics

Where possible, ARIA semantics should be exposed through the standard mechanisms of the desktop accessibility API. For example, for ARIA widgets, compare how the widget is exposed in a similar desktop widget. In general most ARIA widget capabilities are exposed through the role, value, Boolean states and relations of the accessibility API.

User agents should notify assistive technology of state changes. Conversely, assistive technology notification of property changes depends on the method by which an assistive technology communicates with the user agent. For example, the aria-multiline property is not something that changes frequently, whereas the aria-checked state changes frequently in response to user input.

3.2. Conflicts between native markup semantics and ARIA

For the core accessibility API properties of role, name, states, value, etc. there is typically only one of each of them. If there is a conflict, ARIA always wins, because ARIA is essentially an override. In other words, if the native markup says there a link, but the ARIA markup says it is a button, then it should be exposed as a button.

3.3. Exposing attributes that don’t directly map to accessibility API properties

When ARIA roles, states and properties don't directly map to an accessibility API, provide a mechanism to expose the raw ARIA data as a text string. User agents may always expose raw ARIA information through this API regardless of whether there is a direct mapping to an accessibility API.

ARIA also exposes new capabilities that desktop accessibility APIs do not currently cover. ARIA uses object attributes to expose semantics not traditionally found in accessibility APIs. Object attributes are name-value pairs that are loosely specified, and very flexible for exposing things that an accessibility API does not have a specific interface for. For example, the aria-live attribute must be exposed via an object attribute because accessibility APIs have no such property available. Specific rules for exposing object attribute name-value pairs are described throughout this document, and rules for the general cases not covered are in States and Object Properties.

For accessibility APIs that do not have "object attributes" per se, it is useful to find a similar mechanism or develop a new interface to expose name/value pairs. Under the Mac OS X Accessibility Protocol, all getters are already simply name-value pairs and it is possible to expose new semantics whenever necessary. Keep in mind, this also requires working with the assistive technology developers to gain support for the new semantics.

3.4. Role mapping

In ARIA, the role attribute may indicate more than one role. The role value is an ordered set of space-separated tokens where each token must be a valid role token. ARIA includes some roles, such as landmarks and advanced widgets, that are not traditionally part of accessibility APIs. In addition, future versions of ARIA may allow for author-defined roles to be used in the role string. In that case, it is expected that a fallback role may be provided after the custom role, in the role string.

Platform accessibility APIs traditionally have had a finite set of predefined roles that are expected by assistive technologies on that platform. There may not always be a perfect match for an ARIA role to a role in the platform accessibility API.

Another difference is that in platform accessibility APIs, only one or two roles may be exposed through the traditional role mechanisms. In contrast, ARIA allows multiple roles to be exposed. Additional roles may be fallback roles. This may be a backup in case a custom role is unknown to some implementations, or it may be a landmark role. Because landmarks do not generally have mappings in platform accessibility APIs, they may occur anywhere within the role string without affecting how the first widget role is exposed.

The user agent should expose roles so that the standard role mechanism of the accessibility API provides the best-fit widget role, yet the entire role string is also available for parsing:

  1. The first role token with a known mapping to accessibility APIs should be used when mapping to the accessibility API via the standard role mechanism of the accessibility API. Use the role table below and apply any special case rules that are specified.
  2. Roles defined in the ARIA spec as "abstract" should not be mapped via the standard role mechanism of the accessibility API. The abstract roles are:
  3. If no mapping to a standard role in the platform accessibility API is found, the algorithm used to map to a platform accessibility API role should act as if no role attribute is present. In other words, the UA will fall back on normal processing of the base markup for the element with the role attribute. For example, for <table role="log"> use the tag name "table" to determine what platform accessibility API role to use. For <input type="text" role="search">, use the platform accessibility API for a text input.
  4. The entire role string should be exposed in the object attribute "xml-roles". This allows assistive technologies to do their own additional processing of roles.

Dynamic role changes are considered an error in the WAI-ARIA specification, and are discussed in Error Handling.

ARIA roleMSAA roleIAccessible2 role (if different from MSAA)ATK role

NSAccessibility  Role

"alert"ROLE_SYSTEM_ALERT                      ATK_ROLE_ALERT    
"alertdialog"ROLE_SYSTEM_ALERT                      ATK_ROLE_ALERT    
"application"ROLE_SYSTEM_APPLICATION                      ATK_ROLE_EMBEDDED    
"button"ROLE_SYSTEM_PUSHBUTTON. If a "button" has the state aria-haspopup="true" it should be exposed as a ROLE_SYSTEM_BUTTONMENUIf a "button" and aria-pressed is not undefined, it should be exposed in IA2 as IA2_ROLE_TOGGLE_BUTTONATK_ROLE_PUSH_BUTTONNSAccessibilityButtonRole
"checkbox"ROLE_SYSTEM_CHECKBUTTON + object attribute checkable="true"                      ATK_ROLE_CHECK_BOX + object attribute checkable="true"NSAccessibilityCheckBoxRole
"columnheader"ROLE_SYSTEM_COLUMNHEADER                      ATK_ROLE_COLUMN_HEADER    
"combobox"ROLE_SYSTEM_COMBOBOX + STATE_SYSTEM_HASPOPUP. If aria-expanded != "true", expose STATE_SYSTEM_COLLAPSED                      ATK_ROLE_COMBO_BOX + ATK_STATE_EXPANDABLE + object attribute haspopup="true"NSAccessibilityComboBoxRole
"description"No role mapping, use xml-rolesIA2_ROLE_TEXT_FRAMEATK_ROLE_TEXT    
"dialog"ROLE_SYSTEM_DIALOG                      ATK_ROLE_DIALOG    
"document"ROLE_SYSTEM_DOCUMENT                      ATK_ROLE_DOCUMENT_FRAME    
"grid"ROLE_SYSTEM_TABLE                      ATK_ROLE_TABLE    
"gridcell"ROLE_SYSTEM_CELL                      ATK_ROLE_TABLE_CELL    
"group"ROLE_SYSTEM_GROUPING                      ATK_ROLE_PANELNSAccessibilityGroupRole
"heading"None, use xml-rolesIA2_ROLE_HEADINGATK_ROLE_HEADING    
"img"ROLE_SYSTEM_GRAPHIC                      ATK_ROLE_IMAGENSAccessibilityImageRole
"label"ROLE_SYSTEM_STATICTEXTIA2_ROLE_LABELATK_ROLE_LABEL    
"link"ROLE_SYSTEM_LINK. Also, apply special rule to expose STATE_LINKED to link and all its descendants.                      ATK_ROLE_LINKNSAccessibilityLinkRole
"list"ROLE_SYSTEM_LIST + STATE_SYSTEM_READONLY                      ATK_ROLE_LIST    
"listbox"ROLE_SYSTEM_LIST                      ATK_ROLE_LIST. Special case: if a "listbox" has a parent or is owned by (via aria-owns) a "combobox", it should be exposed with ATK_ROLE_MENU.NSAccessibilityListRole
"listitem"ROLE_SYSTEM_LISTITEM + STATE_SYSTEM_READONLY                      ATK_ROLE_LISTITEM    
"marquee"No role mapping, use xml-roles                      ATK_ROLE_PANE    
"menu"ROLE_SYSTEM_MENUPOPUP                      ATK_ROLE_MENU. These objects should not be exposed for a submenu if there is a parent menu item spawning the submenu.NSAccessibilityMenuRole
"menubar"ROLE_SYSTEM_MENUBAR                      ATK_ROLE_MENU_BARNSAccessibilityGroupRole
"menuitem"ROLE_SYSTEM_MENUITEM                      ATK_ROLE_MENU_ITEM
  • If aria-checked is not undefined, support object attribute "checkable"="true"

If the option's parent has a group role, then role="menuitem" maps to NSAccessibilityMenuButtonRole

If the option's parent has a menu role, then role="menuitem" maps to NSAccessibilityMenuItemRole

"menuitemcheckbox"ROLE_SYSTEM_MENUITEM + object attribute checkable=trueIA2_ROLE_CHECK_MENU_ITEM + object attribute checkable="true"ATK_ROLE_CHECK_MENU_ITEM + object attribute checkable="true"NSAccessibilityMenuItemRole
"menuitemradio"ROLE_SYSTEM_MENUITEM + object attribute checkable=trueIA2_ROLE_RADIO_MENU_ITEM + object attribute checkable="true"ATK_ROLE_RADIO_MENU_ITEM + object attribute checkable="true"NSAccessibilityMenuItemRole
"option"ROLE_SYSTEM_LISTITEM + if aria-checked is not undefined, support object attribute "checkable"="true"                      ATK_ROLE_LIST_ITEM
  • If aria-checked is not undefined, support object attribute "checkable"="true"
  • Special case: if an "option" has a parent that was exposed as an ATK_ROLE_MENU, it should be exposed as an ATK_ROLE_MENU_ITEM

If the option's parent has a menu role, then role="option" maps to NSAccessibilityMenuItemRole

If the option's parent has a listbox role, then role="option" maps to NSAccessibilityStaticTextRole

"presentation"Do not expose this object unless it is focusable                      Do not expose this object unless it is focusable    
"progressbar"ROLE_SYSTEM_PROGRESSBAR + READONLY                      ATK_ROLE_PROGRESS_BAR + READONLYNSAccessibilityProgressIndicatorRole
"radio"ROLE_SYSTEM_RADIOBUTTON                      ATK_ROLE_RADIO_BUTTONNSAccessibilityRadioButtonRole
"radiogroup"ROLE_SYSTEM_GROUPING                      ATK_ROLE_PANENSAccessibilityRadioGroupRole
"region"ROLE_SYSTEM_PANE                      ATK_ROLE_PANE    
"row"ROLE_SYSTEM_ROW unless inside a "tree" or "treegrid", in which case ROLE_SYSTEM_OUTLINEITEM                      ATK_ROLE_LIST_ITEM    
"rowheader"ROLE_SYSTEM_ROWHEADER                      ATK_ROLE_ROW_HEADER    
"section"None, use xml-rolesIA2_ROLE_SECTIONATK_ROLE_SECTION    
"separator"ROLE_SYSTEM_SEPARATOR                      ATK_ROLE_SEPARATOR    
"slider"ROLE_SYSTEM_SLIDER                      ATK_ROLE_SLIDERNSAccessibilitySliderRole
"spinbutton"ROLE_SYSTEM_SPINBUTTON                      ATK_ROLE_SPIN_BUTTONNSAccessibilityProgressIndicatorRole
"status"ROLE_SYSTEM_STATUSBAR                      ATK_ROLE_STATUSBAR    
"tab"ROLE_SYSTEM_PAGETAB. Expose SELECTED state if focus is inside tabpanel associated with aria-labelledby.                      ATK_ROLE_PAGE_TAB. Expose SELECTED state if focus is inside tabpanel associated with aria-labelledby.    
"tablist"ROLE_SYSTEM_PAGETABLIST                      ATK_ROLE_PAGE_TAB_LIST    
"tabpanel"ROLE_SYSTEM_PROPERTYPAGE                      ATK_ROLE_SCROLL_PANE    
"textbox"ROLE_SYSTEM_TEXT + IA2_STATE_SINGLE_LINE of aria-multiline is not "true"                      ATK_ROLE_ENTRY + ATK_STATE_SINGLE_LINE of aria-multiline is not "true"NSAccessibilityTextAreaRole
"toolbar"ROLE_SYSTEM_TOOLBAR                      ATK_ROLE_TOOL_BAR    
"tooltip"ROLE_SYSTEM_TOOLTIP                      ATK_ROLE_TOOL_TIP    
"tree"ROLE_SYSTEM_OUTLINE                      ATK_ROLE_TREE    
"treegrid"ROLE_SYSTEM_OUTLINE                      ATK_ROLE_TREE_TABLE    
"treeitem"ROLE_SYSTEM_OUTLINEITEM + if aria-checked is not undefined, support object attribute "checkable"="true"                      ATK_ROLE_LIST_ITEM + if aria-checked is not undefined, support object attribute "checkable"="true"    

3.5. State and Property Mapping

This section describes how to expose additional states and object properties not covered in previous sections of this document. Where possible, API standard states are used. When that is not possible, object attributes (or a similar mechanism) is required.

  1. Compute the managed states such as VISIBLE/INVISIBLE, SHOWING/OFFSCREEN, etc. This typically is done in the same way as for ordinary elements that do not have ARIA attributes present. For FOCUSABLE/FOCUSED, it may be affected by aria-activedescendant—see the rules in aria-activedescendant.
  2. Add in states and object attributes supported by the accessibility implementation for the base markup.
  3. Apply special case rules for the primary role: some roles require additional states to be exposed. For the primary mapped role, look in the role table in Role for additional states and object attributes to expose.
  4. Compute states for the relevant ARIA properties. To determine the relevant ARIA properties, combine the list of the global states and properties with the specific states and properties supported by the roles on the current element. For example, all elements support aria-required, but only some roles such as role="checkbox" support the aria-checked property. To compute the properties see the table below.
  5. For forward compatibility with new ARIA properties in future versions, expose all properties not in this table with an object attribute, removing the "aria-" prefix from the name. For example, aria-foo="bar" would be exposed with an object attribute foo=bar, since aria-foo is not a currently known ARIA property from the spec (it is not already covered by a more specific mapping rule).

ARIA property mapping rule table:

Important Note: any ARIA property of type Boolean or NMTOKEN is undefined if the ARIA attribute is not present, or is set to the zero-length string or "undefined". This does not affect properties of type string, decimal, IDREF or IDREFS.

Also, ensure that states and properties which are not global are only computed on elements with roles that support them.

ARIA stateWhat to expose
aria-activedescendant

Expose as described in aria-activedescendant, and set appropriately when the AT pushes focus changes in a container with this attribute not undefined as described in Handling focus changes from the AT.

Universal Access: if AXFocused is true, post "NSAccessibilityFocusedUIElementChangedNotification" notification when aria-activedescendant value changes

aria-atomic

If not undefined and not false expose atomic="true". In addition, expose container-atomic="true" on all descendants as well as RELATION_MEMBER_OF pointing to this element (the atomic root) as described in Changes to document content or node visibility.

aria-autocomplete
  • if not undefined or "none" expose the value in an object attribute called autocomplete and expose the SUPPORTS_AUTOCOMPLETION equivalent state
aria-busy
  • If "false", clear the BUSY state,  else if not undefined expose the BUSY state
aria-checked
  • If "false", clear the CHECKED state, else if not undefined set the CHECKED state
  • If aria-checked is "mixed" expose ATK_STATE_INDETERMINATE/STATE_SYSTEM_MIXED, unless on a role of "radio" or "menuitemradio" (in those cases tread as "false")
  • In addition, if aria-checked is not undefined expose object attribute checkable="true"
  • Universal Access: "false" => AXValue="0"; "true" => AXValue="1"; "mixed" => AXValue="0.5"
aria-controlsExpose the relations as described in Relations
aria-describedbyExpose the relations as described in Relations
  • In MSAA, expose via accDescription
  • Universal Access: set AXDescription to text value of element found by property value
aria-disabled
  • In MSAA, if aria-disabled is "false", clear STATE_SYSTEM_UNAVAILABLE, else if not undefined set STATE_SYSTEM_UNAVAILABLE
  • In all APIs, if aria-disabled != "true", expose SENSITIVE + ENABLED
  • In addition, aria-disabled="true" has the special property that propagates to all FOCUSABLE descendants of the element
  • Universal Access: set AXEnabled to !aria-disabled
aria-dropeffectExpose as object attribute "dropeffect"
aria-expanded
  • In MSAA, if undefined do nothing, else if "false" set STATE_SYSTEM_COLLAPSED, else set STATE_SYSTEM_EXPANDED
  • in ATK, if not undefined expose ATK_STATE_EXPANDABLE. If not undefined and not "false" expose ATK_STATE_EXPANDED
aria-flowtoExpose the relations as described in Relations
aria-hiddenThis is not used in mapping to platform accessibility APIs. Instead, use information from the layout system to determine if the element is hidden or not. Advisory: it is incorrect use of ARIA if an element with aria-hidden="true" is visible. The aria-hidden property is exposed only so that DOM-based assistive technologies can be informed of visibility changes. However, the layout will be able to provide the most complete set of all truly hidden nodes.
aria-invalidIf "false", clear INVALID_ENTRY or equivalent state, else if not "false" and not undefined, then set INVALID_ENTRY In addition, if not "false" or undefined, expose the value as a text attribute (not object attribute). Current possible values are are "true", "spelling" or "grammar".
aria-haspopup

If "false", clear the HASPOPUP state (MSAA only) and object attribute (both) else if not undefined:

  • In MSAA, expose as STATE_SYSTEM_HASPOPUP
  • In ATK, expose as object attribute haspopup="true"
  • Universal Access: expose AXShowMenu action
Additional rule—this affects the final role exposed for MSAA. If on a push button (HT, change the role to ROLE_SYSTEM_BUTTONMENU
aria-labelExpose in accessible name 
aria-labelledbyExpose the relations as described in Relations as well as in accessible name 
aria-levelExpose value in"level" object attribute and in IAccessible2's groupPosition. May affect RELATION_NODE_CHILD_OF when used on a tree item. See section Group Position.
aria-live

If not undefined, expose the value in an object attribute called "live". Expose a "container-live" object attribute with the value on all descendants as described in Changes to document content or node visibility.

aria-multiline

If "false" clear the MULTI_LINE state, and set SINGLE_LINE, else if not undefined set the MULTI_LINE state and clear SINGLE_LINE

Universal Access: report "textbox" role as AXTextArea

aria-multiselectable

If "false" clear the MULTISELECTABLE state, else if not undefined set the MULTISELECTABLE state
In MSAA also expose STATE_SYSTEM_EXTSELECTABLE to exactly match MULTISELECTABLE.
Expose the AccessibleSelection interface. See Selection.

aria-ownsExpose the relations as described in Relations
aria-pressed
  • If aria-pressed="false" clear the PRESSED state, else if not undefined set the PRESSED state.
  • If aria-pressed is "mixed" expose ATK_STATE_INDETERMINATE/STATE_SYSTEM_MIXED
  • In addition, if aria-pressed is not undefined expose object attribute checkable="true"
  • This property can affect the final role exposed via the platform accessibility API. If not undefined and on a button (ARIA/HTML/XUL), change expose the role as IA2_ROLE_TOGGLE_BUTTON/ATK_ROLE_TOGGLE_BUTTON.
aria-posinsetExpose value in "posinset" object attribute and in IAccessible2's groupPosition
aria-readonly

In MSAA, expose as STATE_SYSTEM_READONLY

If on an element that is editable, e.g. an ENTRY or supports the EditableText interface, make sure that EDITABLE is set to the logical opposite of READONLY

aria-relevantIf not undefined, expose the value in an object attribute called "relevant". Expose a "container-relevant" object attribute with the value on all descendants as described in Changes to document content or node visibility.
aria-requiredExpose as REQUIRED state
aria-selected
  • If aria-selected is "false" clear SELECTED, else if not undefined expose SELECTED
  • If not undefined also expose SELECTABLE
  • If SELECTABLE and not DISABLED, toggle between "true" and "false" as appropriate when the Accessible Selection interface is used on an ancestor with aria-multiselectable as described in Selection.
  • Universal Access: set AXSelected attribute
aria-setsizeExpose value in "setsize" object attribute and in IAccessible2's groupPosition
aria-sortExpose value in "sort" object attribute
aria-valuemax

Expose via AccessibleValue interface as described in Value

Universal Access: set AXMaxValue attribute

aria-valuemin

Expose via AccessibleValue interface as described in Value

Universal Access: set AXMinValue attribute

aria-valuenow

Expose via AccessibleValue interface as described in Value, and set when the AT uses the Value interface to set the value on an element that is not DISABLED or READONLY, and a valid value is chosen. In MSAA, also expose via get_accValue unless aria-valuetext is used to override the value's text equivalent.

Universal Access: set AXValue and post NSAccessibilityValueChangedNotification if necessary

aria-valuetext

Expose in "valuetext" object attribute as described in Value

[ Aaron: this seems correct, is it? ... Universal Access: set NSAccessibilityValueDescriptionAttribute to valuetext string ]

For dynamic ARIA property changes, expose an event such as a state change event to indicate the change occurred. For simplicity and performance the user agent may trim out change events for properties that assistive technologies typically ignore changes in. However, at a minimum, state change events should be fired for changes in:

Other types of changes:

3.6. Special Processing Requiring Additional Computation

3.6.1. Name and Description

3.6.1.1. Text Equivalent Computation

This computation is referred to by both the Name and Description computations described after it.

  • current node - the DOM node currently traversed in order to compute the text equivalent
  • current total text - the text equivalent we have computed up until we have arrived at the current node

To compute the text equivalent for an element:

  1. Prepend a space if necessary: if the current node is an element and is not styled with display: inline, append a space character if the text equivalent result string is not currently empty.
  2. Compute the text equivalent for the current node:
    1. If the current node is hidden and not currently pointed to directly by an aria-labelledby or aria-describedby used in this text equivalent traversal, then, skip the node.

    2. Else if the current node is a text node, append the text contents. It is generally preferable to append the rendered text contents, where whitespace is normalized.

    3. Else if aria-label is present, use the value of the aria-label property for the text equivalent of this node.

    4. Else if aria-labelledby is present, and this node is not already part of an aria-labelledby or accessible name calculation, then process aria-labelledby to generate the text equivalent of this node. Within the aria-labelledby value, process the IDs in the order they occur and ignore IDs in that are not specified on an element in the document. For each ID's associated element, implement this text equivalent computation starting with step 1, appending the results to the total text equivalent result string as they are collected. For example:

      <button aria-labelledby="span" id="btn" /> Text equivalent = "text"—we follow aria-labelledby because this is root node for text equivalent calculation
      <button aria-labelledby="btn" /> No text equivalent, because we follow 1st aria-labelledby but not the 2nd since it is not the root node for the name calculation
      <span id="span">text</span>

    5. Else if the native markup provides a text equivalent, append it to the text equivalent. An example of a native markup text equivalent is alt for HTML <img> or a label from <label for>. However, do not use markup for tooltips here—they are used basically as a last resort under item h.

    6. Append the current user-entered value of this node to the text equivalent. However, in order to avoid redundant presentation of the same text, do not append this text if it will be the first or last part of a text equivalent calculation for the same node that it came from. For example:

      <span role="checkbox" id="cb">Want <input type="text" aria-labelledby="cb"> for breakfast</span>
      <span role="checkbox" id="cb"><input type="text" aria-labelledby="cb"> wants breakfast</span>
      <span role="checkbox" id="cb">I want to eat <input type="text" aria-labelledby="cb"></span>

      Results:

      The text equivalent for <span role="checkbox"> elements below always uses the value from the inner text field, because the text field is part of the text equivalent computation for a different node (the <span role="checkbox>) .  

      For the text equivalent for <input>'s, only case #1 below uses the value for its own label, it's in the middle of the text equivalent calculation. Because the value occurs in the middle of the text equivalent, it is necessary to present its placement within the context of the larger text equivalent.

    7. If the text equivalent for this node is empty, and either the current node's role allows "Name From: subtree"  or the current node is not a control but is part of a label or description, recursively implement this name computation for each child, starting with step 1, appending the results to the total name result string as they are collected. If this recursion only produces white space, reduce it down to an empty string, and use the following rule instead.

    8. Else if the text description for this node is still empty, get the name from tooltip for the current node if any (e.g. title attribute in HTML, tooltiptext attribute or tooltip attribute in XUL) of the current node.

  3. Append a space if necessary: if the current node is an element and is not styled with display: inline, append a space character.
  4. Normalize whitespace, trimming leading and trailing space (including those added in previous steps), and condense other whitespace characters into a single space.
3.6.1.2. Name Computation

To compute the accessible name for an element, start with an empty string:

If aria-label is not present but aria-labelledby is present, collect the name using the text equivalent computation on the elements pointed to by aria-labelledby. Process the IDs in aria-labelledby in the order they occur. Ignore IDs that are not specified on an element in the document.

Else this means that aria-labelledby will not be used, and the accessible name should be computed using the text equivalent computation on the current element.

If the element is an <img> and the text equivalent is empty, then check for the presence of any labeling attribute, specifically aria-label, aria-labelledby, alt or title. The presence of any of these would indicate the author's intention to set an empty text equivalent for decorative or redundant image content. If none of these attributes are present, this indicates the author simply did not provide an accessible label for the image, and the implementation should return an accessible name of NULL instead of "". This hints to the AT to do its own heuristic processing to repair the missing accessible name.

3.6.1.3. Description Computation

To compute the accessible description for an element, start with an empty string:

If aria-describedby is present, collect the description from the elements pointed to by aria-describedby. Process the IDs in aria-describedby in the order they occur. Ignore IDs that are not specified on an element in the document. For each ID use the text equivalent computation.

3.6.2. Widget Values

When the aria-valuenow attribute is supported for a role used on the element, the AccessibleValue interface must be supported on the accessible object to expose. The aria-valuemin and aria-valuemax should be exposed via the AccessibleValue interface.

There may also be a text equivalent for the numerical value, which is set via the aria-valuetext property. That should be exposed via a "valuetext" object attribute, or a similar mechanism if object attributes are not available in the API. When no aria-valuetext is present, then expose a string version of the aria-valuenow in the valuetext object attribute.

In addition, for MSAA, the string should also be exposed via IAccessible::get_accValue.

Changes to aria-valuenow should be exposed via value change events. [davidb: is there any event throttling that should be applied here, or is the cost not too high? (see related group post)]

If the value is not set on a control that requires value, then current value should return an error. This is a valid condition for progressbar, where the current value could be indeterminate.

The AcessibleValue allows values to be set. If the object is not readonly or disabled, it should allow this and the UA should set aria-valuenow to reflect the new value. It is not possible to alter the value in a progress meter since it is always readonly. The implementation should reject values which are less than the aria-valuemin or greater than the aria-valuemax. If the value cannot be set because the object is readonly or disabled, the new value would be out of bounds, the implementation should throw an exception rather than set the value.

Note to authors: a script widget which supports aria-valuenow and is not readonly or disabled should listen for aria-valuenow changes and when it changes, reset the internal state, the aria-valuetext (if used) and the visual state of the widget.

3.6.3. Relations

All relations are globally applicable to any element, so it is not important to check the role before computing them. Relationship attributes use an ID list (space separated list of IDs). A relationship ID matches the element having that ID, that is returned by getElementById with the ID as an argument.

Exposing forward relations:

Computing reverse relations:

  • Check for other elements using ARIA relations that point to the current element's ID, in order to expose the reverse relations
  • If aria-controls points to the element: expose RELATION_CONTROLLED_BY
  • If aria-describedby points to the element: expose RELATION_DESCRIPTION_FOR
  • If aria-flowto points to the element: expose RELATION_FLOW_FROM
  • If aria-labelledby points to the element: expose RELATION_LABEL_FOR
  • If aria-owns points to the element: expose RELATION_NODE_CHILD_OF

If both aria-labelledby and HTML <label for=> are used, the ARIA relation wins and the HTML label relation is ignored.

Computing RELATION_NODE_CHILD_OF for role="treeitem", when aria-owns is not used:

  • If the current treeitem uses aria-level, then walk backwards in the tree until a treeitem is found with a lower aria-level, and point to that. If the top of the tree is reached, then point to the tree itself.
  • If the parent of the treeitem is role="group", then walk backwards from the group until a treeitem is found and point to that. This is the case where role="group" is used to organize levels in the tree.

Computing RELATION_MEMBER_OF from aria-atomic:

  • Check the chain of ancestor elements for aria-atomic="true". All accessible descendants of that element should use the RELATION_MEMBER_OF relation to point to the ancestor that sets aria-atomic="true".

3.6.4. Group Position

The object attributes "posinset", "setsize" and "level" should be exposed when the equivalent ARIA properties are supported by a role used on the element. In addition, on IAccessible2 the same information must be exposed via IAccessible2::groupPosition.

Computing the level if not provided:

  • For role="treeitem", if aria-level is not provided by the author, it must be computed by following the explicit or computed RELATION_NODE_CHILD_OF as described in Relations.

When computing posinset and setsize if not provided:

  • for role="treeitem", walk the tree backward and forward until the explicit or computed level becomes less than the current item's level. Count items only if they are at the same level as the current item.
  • Otherwise, walk backward and forward within the DOM parent, counting items that have the same role.
  • The posinset includes the current item and items before it in the group. The setsize adds to that the number of items in the same group after the current item.

These properties are all 1-based. When the object property is not present or holds a value of "0", it indicates the property is not computed or not supported.

Because these values are 1-based, the current item must be included in the computation. For posinset, add items only if they are before the current item in the DOM. For setsize, also add items after the current item in the DOM.

4. Managed States

4.1. Exposing Supplemental Interfaces

In general the base markup should determine what interfaces are exposed for an accessible object. However, in the following cases ARIA markup changes which interfaces should be exposed:

Although it is not an ARIA-specific issue, for the purposes of accessible web applications it is worth mentioning some additionally useful rules for exposing interfaces:

4.2. Actions

Actions are exposed by the following rules

ARIA Role - Action Map

ARIA Role

Action
alertno
alertdialogno
applicationno
articleno
buttonclick
checkboxcheck/uncheck
columnheaderno
comboboxopen/close
descriptionno
dialogno
documentno
gridno
gridcellno
groupno
headingno
imgno
labelno
linkjump
listno
listboxno
listitemselect/unselect if parent role is listbox
mathno
menuno
menubarno
menuitemclick
menuitemcheckboxclick
menuitemradioclick
optionselect/unselect
presentationno
progressbarno
radioselect
regionno
rowno
rowheaderno
sectionno
separatorno
sliderno
spinbuttonno
statusno
tabswitch
tablistno
tabpanelno
textboxactivate
toolbarno
tooltipno
treeno
treegridno
treeitemactivate + expand/collapse

4.3. Changes to document content or node visibility

Processing document changes is important regardless of ARIA. We document how to do it here, however, because it is so crucial to enable the AJAX and other use cases that often go along with ARIA markup.

Fire these events for text changes:

  1. When text is removed, fire IA2_EVENT_TEXT_REMOVED (IA2) and text_changed:delete (ATK)
  2. When text is inserted, IA2_EVENT_TEXT_INSERTED (IA2) and text_changed:insert (ATK)
  3. When text is changed, fire a removal event followed by an insertion event

Fire these events for node changes where the node in question is an element and has an accessible object:

  1. When a subtree is removed or hidden, fire EVENT_OBJECT_HIDE (MSAA) and children_changed:remove (ATK). The MSAA event called EVENT_OBJECT_DESTROY is not used because this has a history of stability issues and ATs avoid it. In any case, from the user's point of view, there is no difference between something that is hidden or destroyed.
  2. When a subtree is inserted or shown, fire EVENT_OBJECT_SHOW (MSAA) and children_changed:add (ATK).
  3. When a subtree is moved, treat it as a removal from one place and insertion in another
  4. When a subtree is changed (e.g. replaceNode) treat it as a removal and insertion

For node changes where the node is not an element or has no accessible object:

When firing any of the above-mentioned change events, it is very useful to provide information about whether the change was caused by user input (as opposed to a timeout initiated from the page load, etc.). This allows the AT to have different rules for presenting changes from the real world as opposed to from user action. Mouse hovers are not considered explicit user input because they can occur from accidental bumps of the mouse.

To expose whether a change occurred from user input:

Exposing additional useful information about the context of the change:

Additional MSAA events may be necessary:

4.4. Selection

There are two cases for selection:

In the single selection case, it is not always necessary to manage selection events and states separate from focus, since selection mirrors focus. One exception is for tab lists. In the case of a tab, if either the tab or its associated tabpanel has focus, then the tab is considered to be SELECTED. To implement this: the user agent can walk up the parent chain from the focus until it finds the a tabpanel, then traverse the aria-labelledby relation from the tabpanel to the related tab, and mark the found tab as focused.

The multiple selection case occurs when aria-multiselectable="true" on an element with a role that supports that property. There are several important aspects:

  1. Expose the correct states on the container: MULTISELECTABLE and, in MSAA, it is also EXTSELECTABLE
  2. Support the AccessibleSelection interface on the container with aria-multiselectable. The selection interface can be used by an AT to actually set the selection on a descendant. This should fail for the specified descendant if aria-selected is undefined, which indicates the element is not SELECTABLE. It should also fail if the specified descendant is DISABLED or READONLY for any reason. When clearing selection on an item, set aria-selected="false" but do not remove the attribute, so that it is still SELECTABLE. Note to authors: scripts need to watch for mutations to aria-selected, since selection may be caused by an AT and not the mouse or keyboard.
  3. Fire the correct events when aria-selected changes on a descendant, as follows:
ScenarioMSAA/IA2ATK/AT-SPI
Toggle aria-selectedEVENT_OBJECT_SELECTIONADD/EVENT_OBJECT_SELECTIONREMOVE on the current container + EVENT_OBJECT_STATECHANGE on the itemobject::selection_changed + atk_object_notify_state_change on the item
Selection follows focusEVENT_OBJECT_SELECTION then state change event on newly focused item, but arrange events so state change doesn't occur on focused item, to avoid extra selection change announcementsobject:selection_changed + atk_object_notify_state_change, but arrange events so state change doesn't occur on focused item, to avoid extra selection change announcements
Select or deselect many items at once:EVENT_OBJECT_SELECTIONWITHIN is all that is necessary. The state change events may be trimmed out for performance.object:selection_changed. The state change events may be trimmed out for performance

4.5. Menus in MSAA/IAccessible2

Under MSAA special events are required whenever a menu is opened or closed. These events must be nested and symmetrical:

Because screen readers on Windows will typically ignore focus events while menus are opened, it is important to fire the symmetrical EVENT_SYSTEM_MENUPOPUPEND followed by a EVENT_SYSTEM_MENUEND when something other than a menu received focus (e.g. selecting the menu option opened a dialog). In fact, screen readers can become quite confused if the correct ending menu events are not fired.

That said, perfectly symmetrical events are difficult to achieve. Because menus can be made visible hidden using a variety of techniques, it is advisable that an implementation keep track of the menu events fired and ensure symmetrization.

5. Special Document Handling Procedures

5.1. Documents, Handling frame and iframe elements

Computing the accessible name for an outer document accessible:

Computing the accessible name for an inner document accessible:

  1. If a sub-document, do a depth-first name computation using aria-labelledby from the <frame> or <iframe>. If the name is still empty, use the title attribute from the <frame> or <iframe>.
  2. If the name is still empty, use a depth-first name computation from aria-labelledby on the document's root ARIA node. If it is still empty use the title attribute on the root ARIA node.
  3. If the name is still empty, and the <title> element or some other means exists of getting the accessible name, use that.

Computing the accessible description for an inner document accessible:

  1. If a sub-document, do a depth-first description computation using aria-describedby from the <frame> or <iframe>.
  2. If the description is still empty, use a depth-first name computation from aria-describedby on the document's root ARIA node.

Computing container-foo on any node in a sub document: For container-live, container-atomic, container-relevant, container-channel and container-busy, inner nodes override outer nodes from within the same documment, because the inner subtree is the more relevant context. However, outer documents override inner documents, because the outer document author may be different and may wish to define the context for a live iframe. Therefore:

  1. Walk the entire parent chain including that from outer documents, collecting the properties from aria-live, aria-atomic, aria-relevant, and aria-busy into the container-[property] object attribute
  2. If a node sets a given object attribute, set a state that doesn't allow that value to change that object attribute again within the document
  3. When entering a parent document, refresh the state to again allow override of each of these object properties

Computing other properties for an inner document accessible:

  1. For user-controlled properties (aria-selected, aria-valuenow, aria-valuetext, aria-activedescendant), use the ARIA markup on the root ARIA node only
  2. The ARIA properties on the outer document accessible take precedence, on a property-by-property basis
  3. If the outer document accessible does not set a property, the root ARIA node for the inner document is used
  4. Relations are not concatenative. If the outer document accessible sets a relation, that is used instead of anything set on the inner document's root ARIA node.

5.2. CSS Selectors

Support for attribute selectors must include ARIA attributes. For example, .fooMenuItem['aria-haspop=true'] should select all elements with class "fooMenuItem", and ARIA attribute "aria-haspopup" with value true.  The presentation must be updated for dynamic changes to ARIA attributes. This allows authors to match styling with ARIA semantics.

6. Error Handling

6.1. Definitions

6.2. Value type: IDREF and IDREFS

Q: What happens if an invalid ID is specified for an ARIA property?
A: The UA will ignore the ID.

Q: What if the ARIA property contains a mixture of valid and invalid IDs?
A: The UA will return only the objects corresponding to the valid IDs.

Q: What if there is more than one element with the same ID?
A: The first element found with the given ID will be what is used. The behavior will be the same as getElementById, and it is the web author’s responsibility to ensure uniqueness of IDs.

Q: What if the same element is specified multiple times in a single ARIA relation of type IDREFS?
A: [Might need to reword this, I am assuming the return is an array of pointers to accessible objects] The UA will return multiple pointers to the same object.

Q: What happens if more than one ID is specified (space-separated list) for a property that is a single IDREF?
A: The UA will use the whole string (without splitting on spaces) and try to look up an element that has that ID. For instance aria-activedescendant="foo bar" would match id="foo bar".

[IE-specific] Q: What if the author is using the “name” attribute instead of “id”, since they were interchangeable in IE7?
A: IE will only match on the “id” attribute, regardless of the version of the document. We believe that matching only on the “id” attribute is the correct behavior.

6.3. Value type: decimal

Q: What if a non-numeric value is specified for a decimal type?
A: If asking for the string version of the property, the UA will simply return the string specified by the author. However, if a decimal is specifically requested, the UA will fail to convert the string to a decimal and return a default value.

6.4. UA Validation

In general, UAs do not do much validation of ARIA properties. Some minor validation may occur on request, such as making sure valid IDs are specified for ARIA relations, and enforcing things like aria-posinset being within 1 and aria-setsize, inclusive. UAs are not responsible for logical validation, such as the following:

  1. Circular references created by relations, such as specifying that two elements own each other.
  2. Correct usage with regard to DOM tree structure, such as an aria-activedescendant being a DOM-descendant of the element with the relation.
  3. Elements with ARIA roles correctly implement the specified role. For example, UAs do not verify that an element with role=”checkbox” actually behaves like a checkbox.

6.5. Roles

Q. What happens if the author uses an abstract role, or a role that does not map to a standard role for the platform accessibility API?
A: This is defined in the spec:

http://www.w3.org/TR/2009/WD-wai-aria-20090224/#ua_role_identify If a given role in the role attribute is abstract or has no mapping, skip that role. If no known role is found in the role attirbute, the UA will just act as if the role attribute was absent except it would still expose the role attribute's value in the xml-roles object attribute.

Q. What happens if the author changes the role of an element dynamically?
A. This is considered incorrect practice by the ARIA specification, can cause changes in what accessible interfaces need to be supported by an object, and is unexpected by ATs. Therefore, the least expensive way to handle dynamic role changes is used: fire the appropriate invalidation events for object with the role change, so that the AT will update its cache or virtual buffer. The relevant invalidation events are:

6.6. States and Properties 

Q. Some ARIA properties are not global, and are only supported on certain roles. What should be mapped when a dependent ARIA property is used where it is not supported?
A. The user agent should act as if the ARIA property is absent, and not not map the given ARIA property through the platform accessibility API. For example, aria-checked should not be exposed as CHECKED on <div role="grid">

Q. What should be exposed to platform accesibility APIs when an ARIA property contains an unknown or disallowed value?
A.1 When exposing as an object attribute, expose the unknown value—do not vet it against possible values.
A.2 When exposing as a platform API Boolean state, treat "", "undefined" or no attribute present as false. Treat any other value as true.
A.3 Otherwise, ignore the value and treat the property as not present

Q. What should be exposed to platform accessibility APIs when an unknown ARIA property is used?
A. Expose an object attribute with the same name, with the "aria-" prefix removed. The object attribute's value should be equal to the ARIA property's value. This will help with forward compatibility with new ARIA properties in future versions.

Q. What if aria-hidden does not match the reality of whether a node is visible or not?
A. This error condition does not even need to be checked for, because aria-hidden is not necessary when a layout API provides more complete information. Advisory: it is incorrect use of ARIA if an element with aria-hidden="true" is visible. The aria-hidden property is exposed only so that DOM-based assistive technologies can be informed of visibility changes. Since layout APIs will be able to provide the most complete set of all truly hidden nodes, they should be used instead of the aria-hidden attribute.  

Q. If an AT uses a platform accessibility API setter to change aria-valuenow, should the user agent ensure that the new value is within the bounds set by aria-valuemin and aria-valuemax?
A. Yes. Do not set the value if it is out of bounds. Note, however, that it is still the final responsibility of the web application to ensure the validity of user data.

Q. If an AT uses a platform accessibility API getter to get aria-valuenow, should the user agent ensure that it is within the bounds set by aria-valuemin and aria-valuemax?
A. No, simply expose the aria-valuenow whether it is out of bounds or not.

Q. What if an element has the aria-valuetext property set, but not aria-valuenow?
A. Expose the valuetext as defined in this guide, but return an error for any value getter that only returns a numeric type

Q. If an AT uses a platform accessibility API setter to change aria-valuenow, should the user agent ensure that the current element is not disabled or readonly?
A. Yes. Do not set the value if the current element is disabled or readonly

Q. If an AT uses the platform accessibility API to change whether an element is selected, should the user agent ensure that the element is not disabled?
A. Yes. Do not set or clear the selection if the current element is disabled (although it is okay to change the selection for readonly elements)

Q. Should the user agent check whether aria-activedescendant actually points to a descendant or not?
A. No

Q. What if aria-level, aria-setsize or aria-posinset are 0 or negative?
A. Return 1

Q. What if aria-posinset is larger than aria-setsize?
A. Return aria-setsize in place of aria-posinset

Q. What if a required aria property (i.e. required for a given role) is missing for a given widget?
A.

6.7. Propagating errors to ATs

Most errors that occur due to ARIA are not propagated to callers. For example, finding an invalid ID in a list of IDREFS is not a reason to return an error code to the caller. Errors that can propagate are specific to certain ARIA properties.

  1. ChildID and aria-owns: aria-owns appends a list of children to an element. Specifying a child ID outside of the new valid range still returns an error, the same that would occur before when specifying an invalid child ID.

7. Appendices

This section is informative.

7.1. References

This section is informative.

[ARIA]
Accessible Rich Internet Applications (WAI-ARIA) Version 1.0. L. Seeman, M. Cooper, R. Schwerdtfeger, L. Pappas, Editors, W3C Working Draft (work in progress), 4 February 2008. This version of WAI-ARIA is available at http://www.w3.org/TR/2008/WD-wai-aria-20080204/. Latest version of WAI-ARIA available at http://www.w3.org/TR/wai-aria/.
[HTML5]
HTML 5, D. Hyatt, I. Hickson, Editors, W3C Working Draft (work in progress), 22 January 2008, http://www.w3.org/TR/2008/WD-html5-20080122/. Latest version of HTML 5 available at http://www.w3.org/TR/html5/.

7.2. Acknowledgments

This section is informative.

The following people contributed to the development of this document.

7.2.1. Participants in the PFWG at the time of publication

  • Jim Allan (Invited Expert, Texas School for the Blind)
  • Chris Blouch (AOL)
  • David Bolter (Invited Expert, University of Toronto Adaptive Technology Resource Centre)
  • Sally Cain (Royal National Institute of Blind People)
  • Charles Chen (Google, Inc.)
  • Michael Cooper (W3C/MIT)
  • James Craig (Apple, Inc.)
  • Dimitar Denev (Frauenhofer Gesellschaft)
  • Donald Evans (AOL)
  • Steve Faulkner (Invited Expert, The Paciello Group)
  • Kentarou Fukuda (IBM Corporation)
  • Andres Gonzalez (Adobe Systems Inc.)
  • Georgios Grigoriadis (SAP AG)
  • Jon Gunderson (Invited Expert, UIUC)
  • Sean Hayes (Microsoft Corporation)
  • John Hrvatin (Microsoft Corporation)
  • Kenny Johar (Vision Australia)
  • Masahiko Kaneko (Microsoft Corporation)
  • Diego La Monica (International Webmasters Association / HTML Writers Guild (IWA-HWG))
  • Aaron Leventhal (IBM Corporation)
  • Alex Li (SAP AG)
  • William Loughborough (Invited Expert)
  • Anders Markussen (Opera Software)
  • Matthew May (Adobe Systems Inc.)
  • Charles McCathieNevile (Opera Software)
  • James Nurthen (Oracle Corporation)
  • Joshue O'Connor (Invited Expert)
  • Lisa Pappas (Society for Technical Communication (STC))
  • Simon Pieters (Opera Software)
  • David Poehlman (Invited Expert)
  • T.V. Raman (Google, Inc.)
  • Gregory Rosmaita (Invited Expert)
  • Tony Ross (Microsoft Corporation)
  • Janina Sajka (Invited Expert, The Linux Foundation)
  • Martin Schaus (SAP AG)
  • Joseph Scheuhammer (Invited Expert, University of Toronto Adaptive Technology Resource Centre)
  • Stefan Schnabel (SAP AG)
  • Richard Schwerdtfeger (IBM Corporation)
  • Lisa Seeman (Invited Expert, Aqueous)
  • Cynthia Shelly (Microsoft Corporation)
  • Marc Silbey (Microsoft Corporation)
  • Henny Swan (Opera Software)
  • Gottfried Zimmermann (Invited Expert, Access Technologies Group)

7.2.2. Other previously active PFWG participants and other contributors to the Accessible Rich Internet Applications specification

Special thanks to Aaron Leventhal for effort and insight as he implemented a working prototype of accessibility API bindings.

Simon Bates, Judy Brewer (W3C/MIT), Christian Cohrs, Becky Gibson (IBM), Alfred S. Gilman, Andres Gonzalez (Adobe), Jeff Grimes (Oracle), Barbara Hartel, Earl Johnson (Sun), Jael Kurz, Linda Mao (Microsoft), Shane McCarron (ApTest), Dave Pawson (RNIB), Henri Sivonen (Mozilla), Vitaly Sourikov, Mike Squillace (IBM), Ryan Williams (Oracle), Tom Wlodkowski.

7.2.3. Enabling funders

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.