Introduction
The AccDC Technical Style Guide is designed to provide reliable and consistent interaction designs that are accessible to the highest percentage of people possible, and to establish a baseline for Functional Accessibility that can be utilized, built upon, studied, and tested against.
Functional Accessibility means that each component is fully accessible from the keyboard, with or without a screen reader running.
AccDC Technical Style Guide Mirrors:
Please address any direct questions to Bryan Garaventa, or to the Accessible Innovators Group for community support.
AccDC API
- Browse All WhatSock Projects on GitHub
- The AccDC API (Standalone) [ GitHub | Zip ]
- The AccDC API (for jQuery) [ GitHub | Zip ]
- The AccDC API (for Dojo) [ GitHub | Zip ]
- The AccDC API (for MooTools) [ GitHub | Zip ]
- AccDC Bootstrap (Standalone) [ GitHub | Zip ]
- AccDC Bootstrap (for jQuery) [ GitHub | Zip ]
- AccDC Bootstrap (for Dojo) [ GitHub | Zip ]
- AccDC Bootstrap (for MooTools) [ GitHub | Zip ]
- The AccDC Technical Style Guide and Coding Arena (for AccDC Standalone and jQuery) [ GitHub | Zip ]
- The AccDC Technical Style Guide and Coding Arena (for Dojo) [ GitHub | Zip ]
- The AccDC Technical Style Guide and Coding Arena (for MooTools) [ GitHub | Zip ]
AccDC is a JavaScript based Application Programming Interface (API) that can be used with other libraries and frameworks, or by itself, to create new or enhance pre-existing web technologies with accessible features.
This is accomplished by utilizing the AccDC API properties and methods, and by leveraging the features that are available within all instantiated AccDC Objects.
The primary purpose of the AccDC API, is to recursively process AccDC Objects, which are rendered as encapsulated dynamic content components.
The majority of AccDC API properties and methods are prototyped within every AccDC Object, making every AccDC Object fully autonomous and programmatically configurable using JavaScript.
This is how AccDC Objects can dynamically control the behaviors of other AccDC Objects at runtime.
An AccDC Object is literally an instantiated JavaScript Object, which stores all relevant data and AccDC API properties and methods within it.
The shell construct of an AccDC Object declaration is as follows:
var myObjArray = [ {id: 'uniqueObjectId', role: 'Object Role Name' // Other AccDC API property and method declarations go here... }];
The array of AccDC Object declarations is passed as a parameter to the $A()
function, which instantiates them as registered AccDC Objects.
$A(myObjArray);
All instantiated AccDC Objects are then registered within the $A.reg
associative array, which can be queried
directly using the ID of each AccDC Object in order to reference, configure, and control specific objects using JavaScript.
Example:
var dc = $A.reg['uniqueObjectId'];
Or
var dc = $A.reg.uniqueObjectId;
An instantiated AccDC Object can then be programmatically configured by modifying or invoking properties and methods within the object instance.
Examples:
// Set literal content to be rendered dc.source = 'Hello World'; // Set the body as the container insertion point dc.isStatic = 'body'; // Prepend the rendered content to the body content instead of replacing dc.prepend = true; // Set a top level class name for the newly rendered container Div element dc.className = 'banner'; dc.runAfter = function(dc){ // Do something after the content finishes loading }; // Render the new content dc.open();
Alternatively, all of the above property and method declarations can be included within the object
literal declaration, before the object array is passed to the $A()
function.
Example:
var myObjArray = [ { id: 'uniqueObjectId', role: 'Object Role Name', source: 'Hello World', isStatic: 'body', prepend: true, className: 'banner', runAfter: function(dc){ // Do something after the content finishes loading }, runAfterClose: function(dc){ // Do something after the content finishes closing }, // Render the object immediately autoStart: true, // Automatically announce the rendered textual content for screen reader users announce: true }]; // Then register the object array $A(myObjArray);
All AccDC API properties and methods are applicable to AccDC Objects, and are confined within the scope of that object.
To learn about sibling and global overrides for AccDC Objects, view the details about the $A()
function within the AccDC Core API documentation.
AccDC Objects can also be used to store specific data that relates only to that object, which can then be accessed by other AccDC Objects.
Example:
// Save data within one AccDC Object dc.tmp = {form: formElement}; // Then access the data from another AccDC Object or process var dataString = serialize( $A.reg.uniqueObjectId.tmp.form.elements );
All data stored within an AccDC Object remains within the object, even after the close()
method is used to close the object and remove its content from the DOM.
Only the $A()
method will completely destroy an AccDC Object and all of its stored data.
All of the Accessible Component Modules tap into this functionality by interfacing with the AccDC API.
If, for some reason an AccDC Object is not rendering properly when the open()
method is invoked, Debugging Mode can be used to diagnose the cause of the issue.
Example:
// Enable Debugging Mode $A.fn.debug = true;
When set to true, this will throw an alert with specific instructions if the issue is caused by a lack of or improper combination of AccDC API properties.
Debugging Mode is set to false by default.
Currently there are four versions of the AccDC API available:
- The Standalone version, which requires no third party dependencies and is compatible with all JavaScript libraries and frameworks without conflict.
- The jQuery extension, which requires jQuery 1.8.3 or greater.
- The Dojo module, which uses the Dojo AMD Loader.
- The MooTools extension, which requires MooTools 1.4.5 or greater.
Since all Accessible Component Modules plug into the AccDC API, the same module code will work correctly in all AccDC API versions equally.
Example using the Standalone, jQuery, or MooTools AccDC versions:

Example using Dojo:

This will set up AccDC, and load all of the declared modules into the $A
namespace, ready for use within your web application.
If the AccDC Bootstrap module is also loaded, then there is no need to include a setup script.
All configurations are controlled through HTML5 attributes within the markup and by editing the "accdc_bootstrap.js" file as desired to customize functionality.
When the Bootstrap Module is executed, it parses the newly loaded DOM, recognizes class names that correspond with specific Accessible Component Modules, then configures and invokes the specified module using HTML5 attributes within the markup to customize both output and behavior.
Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.
To enable this functionality, simply load the AccDC Bootstrap module after all of the desired Accessible Component Modules have been loaded.
Example using the Standalone, jQuery, or MooTools AccDC API versions:

Example using Dojo:

Some modules refer to offscreen text, which can be used to provide textual information for screen reader users that is not displayed visually and has no impact on visual layout.
The following CSS class has been proven to work well for this purpose, which is the same that is built into AccDC as the "$A.sraCSS" object.
.offscreenText { position: absolute; clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ clip: rect(1px, 1px, 1px, 1px); clip-path: inset(50%); padding: 0; border: 0; height: 1px; width: 1px; overflow: hidden; white-space: nowrap; }
This styling configuration is based on the research done by Thierry Koblentz, which is more fully described at
https://developer.yahoo.com/blogs/tenydnblog/clip-hidden-content-better-accessibility-53456.html
Accessible Component Modules
IMPORTANT: All of the HTML markup syntax examples found within the expandable Accessible Component Module sections represent the minimal code necessary for using the associated JavaScript module included with the AccDC API, though the actual markup is flexible when implemented.
Since the associated JavaScript module handles key attributes such as tabindex, amongst relevant ARIA state and property attributes, these are not included within the HTML markup syntax examples, since assigning these manually would complicate the scripting setup process for each module.
To see how tabindex and relevant ARIA attributes are handled, use a DOM viewer utility to examine the rendered output of each live demo within the Coding Arena, where dynamic behaviors can be observed.
Accordions are a fairly simple control type that are easy to make accessible.
Though similar in both concept and execution to Tab Controls, they are not the same.
A Tab Control has a series of grouped triggering elements that expand and collapse, the rendered content of which is inserted directly after the triggering element group when opened. The container element insertion point for all Tab Control triggering elements is shared between them. Also, the group of triggering elements in a Tab Control has only one tab stop. The arrow keys are then used to switch focus between each Tab, and the Enter or Space key is used to expand the desired Tab content panel.
In contrast, an Accordion has a series of triggering elements that expand and collapse, the rendered content
of which is inserted directly after the triggering element when opened.
The container element insertion points for Accordions are not shared.
Also, all Accordion links appear in the tab order.
The reason why ARIA attributes such as role="tablist"
and role="tab"
are not included within accordions, is
because the insertion of inline content would place dynamic content sections within the same Tablist container,
making it impossible to determine the order of nested Tab controls when present within the inserted content.
The chosen implementation should always match the UI that it's being applied to, to prevent confusion.
The Accordion Module automates these processes by adding all related event handlers and managing all related rendering procedures.
- Accordion with offscreen text to indicate role and state,
aria-controls
,role=region
, andaria-labelledby
: Demo - Accordion with ARIA
role=button
,aria-pressed
,aria-controls
,role=region
, andaria-labelledby
: Demo - Accordion with ARIA
role=link
,aria-expanded
,aria-controls
,role=region
, andaria-labelledby
: Demo
HTML Syntax
Referencing external content:

  Triggering Element One Name

  Triggering Element Two Name

Or referencing internal content:

  Triggering Element One Name

  Triggering Element Two Name

HTML5
attributes are used to configure specific functionality for each accordion expand/collapse link. These include the following:"data-"
- data-src : The resource path and pointer to the ID attribute of the accordion content container element. If set, data-internal should be blank or not included.
- data-internal : The ID attribute of the accordion content container element within the same document. If data-internal is set, data-src should be blank or not included.
- data-insert : The ID attribute of the container element where the accordion content will be inserted when rendered. (This must not be inside the triggering element)
- data-defaultopen="true" : Specifies that the referenced accordion node will open automatically. Only one accordion node per group should include this attribute.
Required attributes:
- All accordion triggering elements must include unique ID attribute values.
Important: The insertion point where accordion content is rendered must be inline with (meaning directly after) the triggering element, to ensure accessibility for screen reader and keyboard only users. (No other active elements or page content should separate them.)
The examples above use DIV tags as container elements, but it doesn't really matter what the container element is, as long as the IDs match up. For instance, the interactive samples in the Coding Arena use DL tags as the main container, DTs to hold the triggering element, and DDs to act as the insertion points, which works well and is easy to format.
Container Element HTML Syntax

 Accordion panel 1 content goes here.

 Accordion panel 2 content goes here.

JavaScript
$A.generateAccordion( 'div.accordionGroup a.accAccordion' , { // Configuration key / value mappings }, document , callbackFunction(dc){ // Run every time an accordion expand/collapse link is toggled // 'dc' is the registered Accordion AccDC Object // dc.triggerObj is the triggering element // dc.containerDiv is the DOM node where all accordion panel content is rendered // dc.loaded reflects whether the accordion panel is currently open } );
Parameters
-
The first parameter is a CSS Selector that specifies all accordion expand/collapse links that are part of the same accordion group.
If multiple accordions are present on the same page, each accordion should be declared separately using the above statement, and the CSS Selector should only reference the expand/collapse node links that apply to that particular accordion, and to no other.
The reason for this is simple. When an accordion is active, it will close all open accordion nodes when an expand link is activated. So if you don't want all of the nodes of every other accordion on the page to be closed at the same time as well, then you should separate them using unique CSS Selectors for each group.
-
The second parameter is used to configure accordion functionality using key / value map overrides.
Example:
{ // Set the hidden text role and state that will be added to the triggering element for screen reader users accordionRole: 'Accordion', accordionState: 'Expanded', // Set the accordion AccDC Object to render literal content // (only when pulling content from within the same page, remove otherwise) mode: 0, // Preload HTML markup to speed rendering // (only when pulling content from an external page, remove otherwise) preload: true, // Preload images to speed rendering // (only when pulling content from an external page, remove otherwise) preloadImages: true, // Set the class name that will be added to the triggering element of the currently open accordion toggleClass: 'open', // Choose whether or not to make accordion expand/collapse links toggles as well isToggle: false // Additional AccDC API properties and methods may be applied here as well if desired. }
-
The third parameter (
contextDOM_Node
) specifies the container DOM node where the accordion is contained, which confines the CSS Selector to the contents of this node. This can also be used to reference accordion groups contained within iFrame documents. -
The fourth parameter is a callback function that can be used to configure additional functionality whenever an accordion is opened or closed.
Programmatic Control
Every accordion node is registered as an AccDC Object, the ID of which matches the ID attribute value on the accordion expand/collapse link. For this reason, all accordion expand/collapse links must have unique ID attribute values.
This means that you can programmatically control each accordion node using JavaScript if desired, like so:
// Get a reference to the accordion AccDC Object for the accordion expand/collapse link with id="uniqueId" var dc = $A.reg['uniqueId']; // Now invoke the object dc.open(); // Or close it dc.close(); // All other AccDC API properties and methods can be applied here as well.
Triggering Element Requirements
Regarding the triggering element for expand/collapse links, you should always use an active element for this purpose to ensure accessibility for both screen reader and keyboard only users.
Within the Coding Arena samples, these are standard links (A tags with an Href attribute), which includes a SPAN tag with a changeable background image. However, you can use whatever type of triggering element you wish, a standard link, button, or image link, with any type of styling. There must be an active element as a triggering element though, to ensure accessibility.
Styling
The sample accordions in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like. This is demonstrated within the "Shell" folders, where there is no CSS styling for the accordion. This is also useful as a practice template for trying out different styling designs with custom content.
When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled accordion will be accessible.
Bootstrapping
Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.
The accordions within the Bootstrap folders are configured using HTML5
attributes within the HTML markup."data-"
When the Bootstrap Module ("accdc_bootstrap.js") is executed, it parses the newly loaded DOM, recognizes the
class "accAccordion"
, then configures the same module declaration as previously described using these HTML5 attributes.
Available HTML5 attributes for the triggering element:
- data-src : The resource path and pointer to the ID attribute of the accordion content container element. If set, data-internal should be blank or not included.
- data-internal : The ID attribute of the accordion content container element within the same document.
If
data-internal
is set,data-src
should be blank or not included. - data-defaultopen="true" : Specifies that the referenced accordion node will open automatically. Only one accordion node per group should include this attribute.
- data-role : The role name that is conveyed to screen reader users within the accordion
link.
Accordion
is set by default if no value is specified. - data-openstate : The open state text that is conveyed to screen reader users within
the accordion link when open.
Expanded
is set by default if no value is specified. - data-insert : The ID attribute of the container element where accordion node content will be inserted. The referenced container element must not be included within the accordion link node.
- data-group : The shared group name for all related nodes within an accordion. This is used to differentiate separate accordion groups within the same document.
Additional HTML5 attributes can be added to enhance functionality by editing the file "accdc_bootstrap.js".
Required attributes for the triggering element:
- class="accAccordion" : The bootstrap class name that specifies an accessible accordion node.
- id : The unique ID of the element. This value is also registered as the ID of the individual
accordion node AccDC Object, making it possible to invoke the object programmatically.
E.G $A.reg.uniqueID.open();
// All other AccDC API properties and methods are similarly available.

Though similar in both concept and execution to Accordions, they are not the same.
An Accordion has a series of triggering elements that expand and collapse, the rendered content of which is
inserted directly after the triggering element when opened.
The container element insertion points for Accordions are not shared.
Also, all Accordion links appear in the tab order.
The reason why ARIA attributes such as role="tablist"
and role="tab"
are not included
within accordions, is because the insertion of inline content would place dynamic content sections within the
same Tablist container, making it impossible to determine the order of nested Tab controls when present within the inserted content.
In contrast, a Tab Control has a series of grouped triggering elements that expand and collapse, the rendered content of which is inserted directly after the triggering element group when opened. The container element insertion point for all Tab Control triggering elements is shared between them. Also, the group of triggering elements in a Tab Control has only one tab stop. The arrow keys are then used to switch focus between each Tab, and the Enter or Space key is used to expand the desired Tab content panel.
The chosen implementation should always match the UI that it's being applied to, to prevent confusion.
The Tab Module automates these processes by adding all related event handlers and managing all related rendering procedures.
- Tab group with ARIA
role=tablist, role=tab, aria-posinset, aria-setsize, aria-expanded, aria-selected, aria-controls, role=tabpanel, aria-labelledby
, andaria-owns
:
Coding Arena/ARIA and Non-ARIA Tabs/ARIA Tabs (Internal Content)/demo.htm
HTML Syntax
Referencing external content:

  Triggering Element One Name

  Triggering Element Two Name

Or referencing internal content:

  Triggering Element One Name

  Triggering Element Two Name

HTML5
attributes are used to configure specific functionality for each Tab expand/collapse link. These include the following:"data-"
- data-src : The resource path and pointer to the ID attribute of the Tab content container element. If set, data-internal should be blank or not included.
- data-internal : The ID attribute of the Tab content container element within the same document. If data-internal is set, data-src should be blank or not included.
- data-insert : The ID attribute of the container element where the Tab content will be inserted when rendered. (This must not be inside the triggering element, and must be the same for all Tab links within the same group)
- data-defaultopen="true" : Specifies that the referenced Tab panel will open automatically. (Only one Tab link per group should include this attribute.)
Required attributes:
-
role="tablist"
must be included within the container element (where all Tab links are contained). -
role="tab"
must be included within all Tab links. - Both the Tablist container element (with
role="tablist"
) and all Tab links (withrole="tab"
) must include unique ID attribute values.
Important: The insertion point where Tab panel content is rendered must be inline with (meaning directly after) the Tablist group, to ensure accessibility for screen reader and keyboard only users. (No other active elements or page content should separate them.)
The examples above use DIV tags as container elements, but it doesn't really matter what the container element is, as long as the IDs match up. For instance, the interactive samples use standard list markup to group related Tab links, which works well and is easy to format.
Container Element HTML Syntax

 Tab panel 1 content goes here.

 Tab panel 2 content goes here.

The following attributes are handled automatically by the Tab Module:
-
tabindex
-
aria-label
-
aria-owns
-
aria-selected
-
aria-expanded
-
aria-posinset
-
aria-setsize
JavaScript
$A.setTabs( 'div.tabGroup a.accTab' , { // Configuration key / value mappings }, useARIA? , document , function(dc){ // Optional callback to execute after a Tab panel opens // 'this' is the same as dc.triggerObj, and is the DOM node for the triggering element // dc.containerDiv is the DOM container node that contains the newly loaded Tab panel content. } );
Parameters
-
The first parameter is a CSS Selector that specifies all Tab expand/collapse links that are part of the same Tablist group.
If multiple Tablist groups are present on the same page, each Tablist should be declared separately using the above statement, and the CSS Selector should only reference the expand/collapse node links that apply to that particular Tablist, and to no other.
The reason for this is simple. When a Tab panel is opened, it will close all other Tab panels when an expand link is activated. So if you don't want all of the nodes of every other Tablist group on the page to be closed at the same time as well, then you should separate them using unique CSS Selectors for each group.
-
The second parameter is used to configure Tab functionality using key / value map overrides.
Example:
{ // Set the Tab panel boundary text that will be conveyed to screen reader users role: 'Tab', accStart: 'Start', accEnd: 'End', // Set the Tab AccDC Object to render literal content // (only when pulling content from within the same page, remove otherwise) mode: 0, // Preload HTML markup to speed rendering // (only when pulling content from an external page, remove otherwise) preload: true, // Preload images to speed rendering // (only when pulling content from an external page, remove otherwise) preloadImages: true, // Set a className that will be added to the triggering element for the currently active tab toggleClass: 'active', // Choose whether or not to make Tab expand/collapse links toggles as well isToggle: false // Additional AccDC API properties and methods may be applied here as well if desired. }
The third parameter (useARIA?
) is a Boolean (true or false), that specifies whether
the Tab Control will be configured as an ARIA Tab widget.
If true, role="tablist"
and role="tab"
must be present within the markup in the correct locations.
If false, role="tablist"
and role="tab"
must not be included within the markup.
Important: The ARIA attributes role="tablist"
and role="tab"
must only be used on client side widgets that don't require a page refresh or navigate to another page.
The reasons why are fully discussed in the article at http://lnkd.in/5nPudh
The fourth parameter (contextDOM_Node
) specifies the container DOM node where the Tablist markup
is contained, which confines the CSS Selector to the contents of this node.
This can also be used to reference Tab groups contained within iFrame documents.
The fifth parameter is a callback function that can be used to configure additional functionality whenever a Tab panel finishes rendering.
Programmatic Control
Every Tab panel is registered as an AccDC Object, the ID of which matches the ID attribute value on the Tab expand/collapse link. For this reason, all Tab expand/collapse links must have unique ID attribute values.
This means that you can programmatically control each Tab panel using JavaScript if desired, like so:
// Get a reference to the Tab AccDC Object for the Tab expand/collapse link with id="uniqueId" var dc = $A.reg['uniqueId']; // Now invoke the object dc.open(); // Or close it dc.close(); // All other AccDC API properties and methods can be applied here as well.
Triggering Element Requirements
Regarding the triggering element for expand/collapse links, you should always use an active element for this purpose to ensure accessibility for both screen reader and keyboard only users.
Within the Coding Arena samples, these are standard links (A
tags with an href
attribute). However,
you can use whatever type of triggering element you wish, a standard link, button, or image link, with any type of styling.
There must be an active element as a triggering element though, to ensure accessibility.
If using an image link however, the img
tag must have a null alt
attribute (alt=""
)
to hide it from screen reader users, and offscreen text must be included if no visible screen text is present.
This will ensure the highest level of accessibility for the highest percentage of screen reader users across all platforms.
Styling
The sample Tabs in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like. This is demonstrated within the "Shell" folders, where there is no CSS styling for the Tablist. This is also useful as a practice template for trying out different styling designs with custom content.
When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled Tablist will be accessible.
Bootstrapping
Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.
The Tablists within the Bootstrap folders are configured using HTML5
attributes within the HTML markup."data-"
When the Bootstrap Module ("accdc_bootstrap.js") is executed, it parses the newly loaded DOM, recognizes the class "accTab"
,
then configures the same module declaration as previously described using these HTML5 attributes.
Available HTML5 attributes for the triggering element:
- data-src : The resource path and pointer to the ID attribute of the tab content container element.
If set,
data-internal
should be blank or not included. - data-internal : The ID attribute of the tab panel container element within the same document.
If
data-internal
is set,data-src
should be blank or not included. - data-defaultopen="true" : Specifies that the referenced tab will open automatically. Only one tab per group should include this attribute.
- data-role : The role name that is conveyed to screen reader users as beginning and ending boundary text for the tab panel content. "Tab" is set by default if no value is specified.
- data-insert : The ID attribute of the container element where tab panel content will be inserted.
- data-group : The shared group name for all related tabs. This is used to differentiate separate tab groups within the same document.
- data-headinglvl : The heading level of the tab panel section for screen reader users. This
should reflect proper nesting. If the tab panel content is inserted within an H1,
data-headinglvl
should be set to '2', and so on. If no value is specified, and if no override is set within accdc_bootstrap.js viaariaLevel:#
, '3' will be set by default.
Additional HTML5 attributes can be added to enhance functionality by editing the file "accdc_bootstrap.js".
Required attributes for the triggering element:
-
role="tablist"
: The ARIA role that specifies a group of tab controls. This must only be included within the element that contains all individual tabs. -
role="tab"
: The ARIA role that specifies an individual tab control. To ensure accessibility, this element must not contain any other active elements. -
class="accTab"
: The bootstrap class name that specifies an accessible Tab link. -
id
: The unique ID of the element. This value is also registered as the ID of the individual Tab AccDC Object, making it possible to invoke the object programmatically.
E.G $A.reg.uniqueID.open();
// All other AccDC API properties and methods are similarly available.
Implementation Notes
As an ARIA widget implementation, the Tablist container element must include the attribute role="tablist"
, and all Tab item links must include
the attribute role="tab"
to ensure accessibility for screen reader users.
Both the Tablist container element and all Tab item links must include unique ID attribute values.
The innerHTML for each Tab item link must contain a textual label, which may be positioned offscreen to hide it visually if desired. (This textual label is necessary so that screen reader users will be able to identify the purpose of the node, and also to ensure proper feedback in iOS devices when using VoiceOver.)
Images may also be used within Tab item links if desired, however, they must include the attribute alt=""
to hide them from screen reader users.
To add tooltips for sighted users, use the Title attribute instead, and make sure that the tooltip text matches the text contained within the textual label if positioned offscreen to hide it visually.
ARIA Comboboxes are used to trigger dynamic lists of related options, such as with auto-suggest filters and custom dropdowns.
Expected behaviors:
- All Combobox controls are keyboard focusable unless explicitly disabled, and must include an accessible close or toggle icon for sighted mouse and mobile touch device users when applicable.
- Interactive editable Combobox controls that use an
Input+type=text
element, open using the Down arrow, are navigated using Up and Down, are saved and closed by pressing Alt+Up or Enter, are canceled and closed by pressing Escape, and support uninterrupted editability when Left or Right or any other non-control key is pressed. - Interactive readonly Combobox controls that use an
Input+type=text
element, open using the Down arrow, are navigated using Up and Down, are saved and closed by pressing Alt+Up or Enter, are canceled and closed by pressing Escape, and require a toggleable triggering element for sighted mouse and mobile touch device users. - Interactive Combobox controls that use simulated active elements such as Divs or Spans, open using the Down arrow or Enter key, are navigated using Up and Down, are saved and closed by pressing Alt+Up or Enter, are canceled and closed by pressing Escape, and act as their own actionable toggle control.
The ARIA Combobox Module automates these processes by adding all related event handlers.
- Startstring Editable and Readonly Comboboxes with ARIA
role=combobox, aria-activedescendant, aria-expanded, aria-controls, aria-autocomplete
, andaria-describedby
:
Coding Arena/ARIA Comboboxes/ARIA Comboboxes (Native Inputs, Editable and Readonly)/demo.htm - Substring Editable Combobox with ARIA
role=combobox, aria-activedescendant, aria-expanded, aria-controls, aria-autocomplete
, andaria-describedby
:
Coding Arena/ARIA Comboboxes/ARIA Comboboxes (Native Inputs, Editable with Substring Match)/demo.htm - Substring Multiselect Editable Combobox with ARIA
role=combobox, aria-activedescendant, aria-expanded, aria-controls, aria-autocomplete
, andaria-describedby
:
Coding Arena/ARIA Comboboxes/ARIA Comboboxes (Native Inputs, Multiselect Editable with Substring Match)/demo.htm - Wordmatch Editable Combobox with ARIA
role=combobox, aria-activedescendant, aria-expanded, aria-controls, aria-autocomplete
, andaria-describedby
:
Coding Arena/ARIA Comboboxes/ARIA Comboboxes (Native Inputs, Editable with Word Match)/demo.htm - Simulated Combobox with ARIA
role=combobox, aria-activedescendant, aria-expanded, aria-controls, aria-autocomplete
, andaria-describedby
:
Coding Arena/ARIA Comboboxes/ARIA Comboboxes (Simulated, Readonly)/demo.htm - Simulated Multiselect Combobox with ARIA
role=combobox, aria-activedescendant, aria-expanded, aria-controls, aria-autocomplete
, andaria-describedby
:
Coding Arena/ARIA Comboboxes/ARIA Comboboxes (Simulated, Readonly Multiselect)/demo.htm
HTML Syntax
The HTML syntax varies depending on which type of implementation is desired.
Editable Input
<input role="combobox" type="text" title="Explicit label text" />
Readonly Input
<input role="combobox" type="text" readonly title="Explicit label text" />
Simulated Active Element

- The markup structure for simulated active elements doesn't require the use of Spans, and may consist of any HTML container markup with embedded tags.
- The tabindex attribute is required on the same container element that includes
role=combobox
to ensure keyboard accessibility, and an empty child container element must be included where dynamically saved values will be inserted.
All Combobox controls are bound to a standard Select element instance, which may be hidden within the page using CSS, or dynamically generated using JavaScript to support dynamic population via AJAX.
To enable multiselect functionality, add the attribute multiple="multiple" to the hidden select element. (Only available when using the ARIA Combobox Module R2.0 or greater.)
<select name="control-name"> <option value="value-1"> Value 1 name </option> <option value="value-2"> Value 2 name </option> <option value="value-3"> Value 3 name </option> </select>
To set a default value for the Combobox other than index[0]
, add the selected
attribute to the default option.
The following attributes are handled automatically by the Combobox Module:
-
aria-activedescendant
-
aria-expanded
-
aria-controls
-
aria-autocomplete
-
aria-describedby
-
role=listbox
-
role=option
JavaScript
// Create a new Combobox instance and bind the relevant elements var myCombobox = new $A.Combobox( selectElementDOM-Node , inputDOM-Node , optionalChildDOM-Node ); // Configure settings here prior to invocation // Then invoke the Combobox for auto-rendering myCombobox.start();
Parameters
-
The first parameter is the hidden Select element DOM node that will be bound to the Combobox control.
-
The second parameter is the focusable
role=combobox
element that will be bound to the hidden Select element. -
The third parameter is the embedded child container element that will be bound to the
role=combobox
element, which is only applicable if therole=combobox
element is not a standard Input or Textarea element.
Programmatic Control
After a Combobox control is instantiated, the following public properties and methods are available.
Methods:
// Set the listbox to render all Select Options regardless of the current value myCombobox.setShowAll(Boolean); // Default: False // Enable full listbox content browsing from the keyboard when the down arrow key is pressed. (Applicable only when the value is empty.) myCombobox.setShowAllIfEmpty(Boolean); // Default: False // Set the listbox to render only Select Options that match the substring value myCombobox.setSubstringMatch(Boolean); // Default: False // Set the listbox to render only Select Options that include all of the space delimited words in the current value myCombobox.setWordMatch(Boolean); // Default: False // Set the Combobox to automatically display the currently selected value within the hidden Select element onStart myCombobox.setDefault(Boolean); // Default: True // Set the currently selected listbox value to automatically be saved when focus moves away from the Combobox control myCombobox.setAutoComplete(Boolean); // Default: False // Set the parent/child tag markup structure for the dynamically rendered listbox myCombobox.setTags({ parentTag: 'ul', childTag: 'li' }); // Set dynamic class names myCombobox.setClassNames({ toplevelClass: 'toplevel-div clearfix', // Top level Div class of Combobox listbox middleClass: 'middle-div clearfix', // Mid level Div class of Combobox listbox listboxClass: 'listbox clearfix', // // parentTag class optionClass: 'option clearfix', // childTag class activeClass: 'active', // Currently active Combobox listbox option toggleClass: 'pressed' // Pressed state class of the altTrigger element }); // Set CSS autopositioning relative to the triggering Combobox element. // Accepted AccDC API values between 0-disabled-default and 12 // For details, see WhatSock.com > Core API > CSS > .autoPosition myCombobox.setAutoPosition(Number); // Default: 0 // Set a positive or negative top/left offset to be applied to the autoPosition property calculation myCombobox.setOffset({ top: Number, left: Number }); // Set the number of listbox options to render when displayed myCombobox.setSize(Number); // Default: 5 // Set a different element to act as an autoPosition focus element instead of the Combobox control myCombobox.setPosAnchor(alternateDOM-Node); // Will not change the DOM insertion point and reading order // Set a different element to act as an insertion point and autoPosition focus element instead of the Combobox control myCombobox.setTargetObj(alternateDOM-Node); // Will change the DOM reading order // Invoke the Combobox control and apply all saved settings myCombobox.start(); // Close the Combobox control and pause functionality myCombobox.stop(); // Manually open the Combobox listbox using all applied settings myCombobox.open(); // Set a handler to execute every time the Combobox listbox is rendered myCombobox.onOpen(function(dc){ // this = the Combobox control // dc = the AccDC Object instance for the Combobox listbox }); // Manually close the Combobox listbox myCombobox.close(); // Set a handler to execute every time the Combobox listbox is closed myCombobox.onClose(function(dc){ // this = the Combobox control // dc = the AccDC Object instance for the Combobox listbox }); // Set a toggle control to open or close the Combobox listbox // Must always be set when implementing readonly Input+type=text elements to ensure sighted mouse and mobile touch device support myCombobox.setAltTrigger(toggleElementDOM-Node); // Set a handler to execute every time the toggle altTrigger element is activated myCombobox.onTriggerChange(function(altTriggerElement, toggleState){ // this = altTriggerElement // toggleState = true or false }); // Set a handler to execute every time a new value is saved to the Combobox control // This will override the default functionality myCombobox.onSelect(function(optionName, optionValue, comboboxControl, selectElement){ // this = comboboxControl // optionName = the visible string for the hidden Select option that is highlighted. // optionValue = the value attribute for the hidden Select option that is selected. This parameter changes to an array of selected option nodes when multiple is set instead. (Only available when using the ARIA Combobox Module R2.0 or greater.) // comboboxControl = the Combobox control element // selectElement = the hidden Select element // Save the new value accordingly // then return the saved string to prevent auto reopening of the Combobox listbox return 'saved string'; }); // Set multiple divider to break up list item markup properly when updated. // Automatically becomes available when the multiple attribute is set on the hidden select element. (Only available when using the ARIA Combobox Module R2.0 or greater.) myCombobox.setMultipleDivider(function(values){ // 'values' is an array of string names for the selected option nodes. return values.join(' '); }); // Clear all selected options when multiple is set on the hidden select element. // (Only available when using the ARIA Combobox Module R2.0 or greater.) myCombobox.clearAll(); // Enable auto saving of checked options, even when typing to narrow the filtered list of options at the same time. // Applicable only when Multiselect is enabled. myCombobox.setAutoSaveIfChecked(Boolean); // Default: False // Set a character minimum when typing into an editable combobox before autosuggested options are rendered. // (Only available when using the ARIA Combobox Module R2.0 or greater.) myCombobox.setCharMin(#); // Default = 0 // Get the current value of the hidden select element // Returns a value property string for single select elements, or an array of selected option DOM nodes when the multiple attribute is set on the select element. // (Only available when using the ARIA Combobox Module R2.0 or greater.) myCombobox.getValue(); // Manually resynchronize the hidden Select to rebuild available Options for the Combobox listbox // This can be used to repopulate rendered options after remote API queries via AJAX cause the hidden Select to contain new Options myCombobox.update(); // Set a string to be announced to screen reader users when the Combobox control receives focus myCombobox.setPromptText(String); // Default: '' // Set a name for the offscreen Close link for screen reader users // Necessary for non-sighted touch screen device users to detect the end of the Combobox listbox when rendered // To disable the offscreen Close link when needed, pass a null value ("") to the method. myCombobox.setCloseText(String); // Default: 'Close Popup'
Properties:
// Access the hidden Select element DOM node myCombobox.select // Access the role=combobox element DOM node myCombobox.combobox // Access the dynamically rendered listbox AccDC Object, including all AccDC API properties and methods // View the Core API tab at WhatSock.com for a full index of available AccDC API properties and methods. myCombobox.dc
Styling
The samples in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.
You can change the styling however you wish to fit the layout of any UI, and the comboboxes will still be accessible to both screen reader and keyboard only users regardless. Simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus.
An ARIA Data Grid is one of the most complicated of ARIA Widget types to make accessible, since it involves many different types of user interaction.
Expected behaviors: The entire grid should have only one tab stop, one cell should be focusable at a time, the arrow keys should move focus between cells, Home and End should move focus to the beginning or end of a row, PageUp and PageDown should open the previous or next page of the grid, Alt+PageUp and Alt+PageDown should move focus to the first or last page in the grid, Space and Enter should activate the current cell or row, and textual equivalents should indicate the role and state of each interactive control type for screen reader users.
The Data Grid Module automates these processes by adding all related event handlers and managing all related rendering procedures.
- Grid control with ARIA
role=grid, role=rowgroup, role=row, role=gridcell, role=rowheader, role=columnheader, aria-describedby, aria-selected, aria-owns
, andaria-labelledby
:
Coding Arena/ARIA Data Grids/ARIA Data Grid (Dynamic)/demo.htm
HTML Syntax

The following attributes are handled automatically by the Data Grid Module:
-
tabindex
-
aria-owns
-
role=grid
-
role=rowgroup
-
role=row
-
role=gridcell
-
role=columnheader
-
role=rowheader
-
aria-rowindex
-
aria-colindex
-
aria-labelledby
-
aria-describedby
-
aria-selected
-
title
-
aria-hidden
JavaScript
var grid = new $A.DataGrid( ContainerNodeOrID );
Parameters
-
The first parameter specifies the container element where the data grid will be rendered, and may be a DOM node or an ID string.
Programmatic Control
// Set the registered columns including unique IDs and label text // The order of items in the array will dictate the default column ordering when rendered grid.mapColumnNames([ { // ID that is associated with all cells in the column id: 'col1id', // The text that will be rendered as the column header lbl: 'User Name', // Set an optional class to be added to all cells within the column colClass: 'col1' }, { id: 'col2id', lbl: 'Email Address', colClass: 'col2' }, { id: 'col3id', lbl: 'Publish Record', colClass: 'col3' } ]); // Programmatically change the order of rendered columns // This method rearanges the array order of the objects passed to grid.mapColumnNames(ObjArray) // Which is used to determine rendering order // This must be followed by grid.open() to rerender the grid after a change is made // E.G Change the third column to the first column grid.changeColumnOrder(2, 0); // Enable row headers and specify the column ID to be used for this purpose // This must be followed by grid.open() to rerender the grid after a change is made grid.enableRowHeaders(true, 'col1id'); // Or disable grid.enableRowHeaders(false); // Set a maximum number of rows to render before pagination is applied // If set to 0, all records will render and no pagination will occur // This must be followed by grid.open() to rerender the grid after a change is made grid.setRowMax(25); // Enable or disable editability for grid cells // This will render an edit field for strings or handle toggle events for buttons. // This must be followed by grid.open() to rerender the grid after a change is made grid.editable(true); // Or to disable grid.editable(false); // Add rows to a grid instance grid.add(rowObject_or_rowObjectArray); // Each row must adhere to the following object literal format: { id: 'uniqueRowId', cells: { 'col1id': { // Set the cell type, may be either 'text' or 'toggle' // Defaults to 'text' if omitted type: 'text', // Set an optional readonly flag to disable editability if the grid is editable // Defaults to false if omitted readonly: true, // Set the initial value of the cell value: 'My User Name' }, 'col2id': { value<EMAIL_ADDRESS>}, 'col3id': { type: 'toggle', readonly: false, value: true, // For toggles, set the name property to specify a visual textual label name: 'Published', // For toggles, specify an optional class to be added when the toggle is set to true // This will override the general toggle class specified within grid.setStaticClasses toggleClass: 'toggle-button-pressed' } } } // Set a value changed listener for handling serverside posting when cell values change grid.setChangeListener(function(originalCellObject, newValue, rowObject, gridInstance){ // rowObject reflects the same object passed to grid.add // so that rowObject.id reflects the original unique row ID // originalCellObject reflects the cell object instance passed within 'cells' when passed to grid.add // and cellObject.id reflects the column ID, so that rowObject.id and cellObject.id can be used as X Y coordinates to identify the correct cell in the grid. // Compare originalCellObject.value with newValue to perform input validation or other processes. // To prevent rendering the changed input or new toggle state, simply return false }); // Enable or disable double click or single click mouse interaction for selectable rows and editable cells // This must be followed by grid.open() to rerender the grid after a change is made // When set to false, a single mouse click will toggle selectability or trigger an edit action grid.useDblClick(false); // Enable or disable row selectability // This must be followed by grid.open() to rerender the grid after a change is made // When set to true, editability will automatically be set to false to prevent functionality and keyboard accessibility conflicts grid.setSelect({ enable: true, // Set a class to be added to the TR node every time a row is selected toggleClass: 'selected', // Set single or multiSelect multiSelect: false, // Use ARIA for selection or cross-platform offscreen text instead // Important: The use of aria-selected for row selection is not well supported by screen readers at this time ariaSelect: false, // Choose whether rendering another page will automatically unselect previously selected rows // Set to false to unselect rows automatically, or true to keep selection active preserve: false, // Set a callback to execute every time a row is toggled callback: function(rowObject, state, prevSelectedRowsArray, gridInstance){ // rowObject is the activated row object. // rowObject.rowNode is the TR DOM node for the toggled row. // 'state' reflects the proposed state change, which is the opposite of rowObject.selected. // prevSelectedRowsArray is an array of all previously selected rowObjects, not counting the current rowObject. // To cancel the toggle action, return false } }); // Or pass single properties to set functionality grid.setSelect({ enable: false }); // Unselect all previously selected rows grid.unselectAll(); // Select all rows on the currently rendered page grid.selectAll(); // Get an array of all currently selected rowObjects // Each rowObject reflects the same object literal passed in grid.add() // Get an array of selected rowObjects var selected = grid.getSelected(), // Get the row ID for the first selected row rowId = selected[0].id, // Or get the TR DOM node of the first selected row rowNode = selected[0].rowNode; // Programmatically select one or more rows using an array of row IDs grid.select(['rowId1', 'rowId2']); // Enable or disable row deletion // This must be followed by grid.open() to rerender the grid after a change is made // When enabled, the Delete key will delete all currently selected rows from the grid and destroy their rowObjects in the cache // Selectability must be set to true for this functionality to be used grid.setDelete({ enable: true, // Set a function to execute prior to deletion runBefore: function(selectedRowIDs_array){ // Return false to cancel deletion }, // Set a callback to execute on every row that is deleted callback: function(rowObject, gridInstance){ // rowObject.id is the table row ID that is being deleted // alert(rowObject.id); // return false to cancel deletion from the grid }, // Set a function to execute after deletion is completed runAfter: function(deletedRowIDs_array){ // Do something } }); // Or to disable grid.setDelete({ enable: false }); // Programmatically delete all currently selected rows and destroy their rowObjects in the cache grid.deleteRows(); // Programmatically delete one or more rows and destroy their rowObjects in the cache using an array of row IDs grid.deleteRows(['rowId1', 'rowId2']); // Programmatically delete all rows in the grid instance and destroy their rowObjects in the cache grid.deleteAllRows(); // set accessible text for screen reader users grid.setAccessibleText({ // Set offscreen and tooltip text for toggle cells toggleButtonRole: 'Toggle Button', toggleButtonState: 'Pressed', disabledText: 'Disabled', // Set the page text to be announced to screen reader users during infinite scrolling. E.G "Page 2", "Page 3", etc. pageRole: 'Page', // Set the active state and help tooltip text for mouse users selectState: 'Selected', editLinkAction: 'Editable', dblClickTitle: 'Click to activate', // Set the title text for the edit field editFieldTitle: 'Press Enter to save, or Escape to cancel.' }); // Set static classes grid.setStaticClasses({ // General Table element class for the grid gridClass: 'data-grid', // Additional Table element class when the grid is set to Readonly gridReadOnlyClass: 'data-grid-readonly', // Additional Table element class when the grid is set to Editable gridEditableClass: 'data-grid-editable', // Additional Table element class when the grid is set to Selectable gridSelectableClass: 'data-grid-selectable', // General TR element class for the grid gridRowClass: 'data-grid-row', // Additional TR element class when a grid row has focus gridRowFocusedClass: 'data-grid-row-focused', // General TH and TD element class for the grid gridCellClass: 'data-grid-cell', // Additional TD element class when a grid cell is set to Readonly cellReadOnlyClass: 'data-grid-cell-readonly', // Additional TD element class when a grid cell has focus gridCellFocusedClass: 'data-grid-cell-focused', // General STRONG element class for grid text cells gridCellLinkClass: 'data-grid-cell-link', // General STRONG element class for grid toggle cells gridCellToggleClass: 'data-grid-cell-toggle', // Additional STRONG element class for grid toggle cells when set to True gridCellTogglePressedClass: 'data-grid-cell-toggle-pressed', // General DIV and INPUT element class for grid edit field popups editFieldClass: 'data-grid-cell-link-edit' }); // Get the total number of rows in the grid instance grid.totalRows(); // Pagination: Get the current page number grid.currentPage(); // Pagination: Get the total number of pages in the grid instance grid.totalPages(); // Set a page index changed listener to execute every time the current or total number of pages changes within the grid instance grid.setPageIndexChangeListener(function(currentPage, totalPages, gridInstance){ // Do something }); // Open a specific page without rerendering the parent grid grid.openPage(number); // Open the first page in the grid grid.firstPage(); // Open the previous page in the grid grid.prevPage(); // Open the next page in the grid grid.nextPage(); // Open the last page in the grid grid.lastPage(); // Execute listener every time a grid object is opened in the DOM grid.setOpenListener(function(container, dc, gridInstance){ // 'dc' is the grid AccDC Object }); // Execute listener every time a grid object is closed in the DOM grid.setCloseListener(function(container, dc, gridInstance){ // 'dc' is the grid AccDC Object }); // Execute listener every time a grid TR object is rendered in the DOM grid.setAddListener(function(rowObject, dc, gridInstance){ // rowObject.id is the unique row ID as passed in grid.add() // rowObject.rowNode is the rendered TR DOM node // 'dc' is the grid AccDC Object }); // Execute listener every time a grid TR object is removed from the DOM grid.setRemoveListener(function(rowObject, dc, gridInstance){ // rowObject.id is the unique row ID as passed in grid.add() // rowObject.rowNode is the rendered TR DOM node // 'dc' is the grid AccDC Object }); // Execute listener every time a grid TD node receives focus grid.setMoveListener(function(newCell, oldCell, dc, gridInstance){ // 'newCell' is the TD DOM node that has been given focus // 'oldCell' is the TD DOM node that used to have focus // 'dc' is the grid AccDC Object }); // Assign a character maxLength value for the edit text popup grid.setEditMaxLength(255); // Set a positioning override for the placement of the edit text popup // Must return an object literal that contains the following properties: top, left, width, height grid.setEditOffset(function(cellObject){ // cellObject.cellNode is the DOM node for the TD element that has focus // cellObject.cellNodeA is the DOM node for the STRONG element contained within the TD element that has focus var o = $A.xOffset(cellObject.cellNodeA); // Get top and left properties o.height = $A.xHeight(cellObject.cellNodeA); // Add height o.width = $A.xWidth(cellObject.cellNodeA); // Add width return o; }); // Set an edit field load listener to execute every time the string edit field is opened for a cell grid.setEditLoadListener(function(editFieldNode, cellObject){ // editFieldNode is the rendered edit Input element // cellObject is the cellObject that was triggered, providing access to all data associated with that cell // E.G // cellObject.cellNode is the actionable TD node that was activated // cellObject.value is the original value of the cell // cellObject.id is the column id for that cell // cellObject.rowObject.id is the unique row ID for that row // cellObject.rowObject.rowNode is the TR node for that row }); // Set the value of a specific cell in the grid using its unique row ID and column ID as X Y coordinates // Row ID refers to the same value stored within rowObject.id, and col ID refers to the same value stored within cellObject.id grid.setValue('rowID', 'colID', value); // Get the value of a specific cell in the grid using its unique row ID and column ID as X Y coordinates // Row ID refers to the same value stored within rowObject.id, and col ID refers to the same value stored within cellObject.id grid.getValue('rowID', 'colID'); // Programmatically store data within a specific cell in the grid using its unique row ID and column ID as X Y coordinates // Row ID refers to the same value stored within rowObject.id, and col ID refers to the same value stored within cellObject.id // When set, the data is alternatively available within the cellObject via cellObject.data['keyname'] grid.setData('rowID', 'colID', 'keyname', data); // Programmatically retrieve data within a specific cell in the grid using its unique row ID and column ID as X Y coordinates // Row ID refers to the same value stored within rowObject.id, and col ID refers to the same value stored within cellObject.id grid.getData('rowID', 'colID', 'keyname'); // Open a grid instance and render a page within the DOM // If no page number is passed as the first parameter, then 1 is inferred by default grid.open(); // Or to open a specific page grid.open(number); // Close a grid instance and remove it from the DOM // This will not delete any of the cached rowObjects that were added via grid.add() grid.close(); // Programmatically set focus to the grid // This always references the TD node that is currently active grid.focus(); // Access the grid AccDC Object instance for optional modification var dc = getAccDCObject(); // Access the container DOM node var myContainer = grid.container;
Styling
The sample data grids in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.
You can change the styling however you wish to fit the layout of any UI, and the data grids will still be accessible to both screen reader and keyboard only users regardless.
Simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled data grid will be accessible.
Implementation Notes
Notes about keyboard interactivity
A focusable ARIA Grid is a complicated concept, and there are only a certain number of keyboard commands available that don't directly conflict with the screen reader or browser. The following keyboard commands should not be used for this reason:
- Control+PageUp/PageDown: Is automatically intercepted by JAWS and never gets passed through to the grid.
- Control+Up/Down: Is automatically intercepted by JAWS and never gets passed through to the grid.
- Alt+Home: Automatically loads the home page in the browser.
- Alt+Left/Right: Automatically activates the Back and Forward buttons in the browser.
Notes about mouse interactivity
When activating a selectable row or editable cell using the mouse, double click must be used. If a single click is used to0 invoke this functionality, it will conflict with screen reader behavior. For example, when browsing the page using JAWS in Virtual Cursor mode, it is necessary to press Enter on the desired grid cell to enter Applications Mode. When JAWS does this, it automatically activates the click event, which automatically invokes selection or editing for that cell.
When double click is used instead, this conflict does not occur. Single tapping of a selectable or editable cell using a touch screen device however, works using one click.
The ARIA Date Picker is a complex control type with a simple implementation.
Expected behaviors: The associated INPUT field should not include readonly, an external triggering element should activate the date picker, the arrow keys should move between calendar cells and the calendar should scroll automatically between months, PageUp/PageDown should switch between months, Alt+PageUp/PageDown should switch between years, Enter should activate the selected date, and pressing Escape or Tab should close the calendar and return focus to the triggering element.
The Calendar Module automates these processes by adding all related event handlers and managing all related rendering procedures.
- Basic compound component date picker control with ARIA
role=button, role=link, aria-label, role=dialog
, androle=application
:
ARIA Date Picker (Basic) - Basic Editable Auto Open compound component date picker control with ARIA
role=button, role=link, aria-label, role=dialog
, androle=application
:
ARIA Date Picker (Basic, Auto Open) - Basic ReadOnly Auto Open compound component date picker control with ARIA
role=button, role=link, aria-label, role=dialog
, androle=application
:
ARIA Date Picker (Basic, ReadOnly Auto Open plus Disabled Ranges) - Disabled date range compound component date picker control with ARIA
role=button, role=link, aria-label, aria-disabled, role=dialog
, androle=application
:
ARIA Date Picker (with Disabled Weekends) - Comment enabled compound component date picker control with ARIA
role=button, role=link, aria-label, role=dialog
, androle=application
:
ARIA Date Picker (with Tooltip Comments) - Editable comments compound component date picker control with ARIA
role=button, role=link, aria-label, role=dialog
, androle=application
:
ARIA Date Picker (with Editable Tooltip Comments)
HTML Syntax
<input type="text" id="dateInputId" title="Label text if no Label element is associated" />  Calendar Icon Name
Form field HTML markup requirements:
- The INPUT field must not be set to readonly, so that users can manually edit date string entries.
- Form field constraints, such as the desired date string format, must also be included with the form field label to maximize clarity. E.G "MM/DD/YYYY"
JavaScript
$A.setCalendar( 'UniqueCalendarId' , $A.getEl('datePickerId'), $A.getEl('dateInputId'), EnableComments<true/false> , clickHandlerCallbackFunction(ev, dc, targetElementObj){ // Configure date string and save it within targetElementObj targetElementObj.value = dc.range.wDays[dc.range.current.wDay].lng + ' ' + dc.range[dc.range.current.month].name + ' ' + dc.range.current.mDay + ', ' + dc.range.current.year; // Then close the calendar dc.close(); }, { // Configuration key / value map overrides });
Parameters
-
The first parameter must be unique for every calendar declaration, since this is registered as the ID of the Calendar AccDC Object when instantiated.
-
The second parameter is the DOM object for the triggering element.
-
The third parameter is the DOM object for the target INPUT element.
-
The fourth parameter is a Boolean that determines whether comments will be displayed when associated with dates. False is set by default if no value is specified.
-
The fifth parameter specifies a callback function where the returned date string can be customized.
-
The sixth parameter is a key / value map where overrides can be declared to further customize functionality.
Example:
{ // Configure optional overrides // If not included, all of the below values are set by default // Set role name text for screen reader users role: 'Calendar', // Short help text message that is automatically announced to screen reader users when the calendar first opens. helpTextShort: 'Press H for help.', // Set screen reader text to automatically be announced when H is pressed. // This is also set within the data-helptext attribute in the top level div element of the calendar for CSS pseudo element referencing via attr(data-helptext) for sighted keyboard only users if desired. helpText: 'Press the arrow keys to navigate by day, PageUp and PageDown to navigate by month, Alt+PageUp and Alt+PageDown to navigate by year, or Escape to cancel.', // Set tooltip text tooltipTxt: 'Press Escape to cancel', disabledTxt: 'Disabled', markedTxt: 'Selected', commentedTxt: 'Has Comment', prevTxt: 'Previous', nextTxt: 'Next', monthTxt: 'Month', yearTxt: 'Year', // Set month names months: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ], // Set short and long weekday names days: [ { s: 'S', l: 'Sunday' }, { s: 'M', l: 'Monday' }, { s: 'T', l: 'Tuesday' }, { s: 'W', l: 'Wednesday' }, { s: 'T', l: 'Thursday' }, { s: 'F', l: 'Friday' }, { s: 'S', l: 'Saturday' } ], // Switch the behaviour when the PageUp or PageDown keys are pressed to a "natural" behaviour // (PageUp goes to previous month, PageDown goes to next month) pageUpDownNatural: false, // Append a "dayToday" CSS class to the current day cell element - this allows styling to be targeted to this specific element highlightToday: true, // Fill in the day cells outside of the current month so that the calendar grid is always filled with day cells drawFullCalendar: true, // Run custom functions at the end of the code within the following component functions. // Receives a single parameter "dc", which provides access to the Datepicker object. runBefore: function (dc) { console.log('runBefore'); console.log(dc); }, runAfterClose: function (dc) { console.log('runAfterClose'); console.log(dc); }, // Override the character used on the month / year change buttons leftButtonYearText: '<', rightButtonYearText: '>', leftButtonMonthText: '<', rightButtonMonthText: '>', // Specify if the calendar should open when the input field receives focus. // If true, the Down arrow must be pressed to move focus from the input field into the calendar for manual traversal, and Escape will collapse the calendar. openOnFocus: false, openOnFocusHelpText: 'Press Down arrow to browse the calendar, or Escape to close.', // Display a Close button showEscBtn: true, escBtnName: 'Close', escBtnIcon: '×', // Set specific start / end boundaries of a date range. Can be Date objects (absolute boundaries), or positive/negative integers (relative boundaries). // If undefined, no date range will be enforced. minDate: undefined, maxDate: undefined, // Using a token system, set a specific date string format to be used when setting the selected value into the calendar input box // 'YYYY': 4 digit year, 2019 // 'MMMM': Full name of month, January, etc. // 'dddd': Full name of weekday, Monday, etc. // 'MM': 2 digit month, 01, etc. // 'DD': 2 digit day, 01, etc. // 'Do': getDateOrdinalSuffix, 1st, 2nd, 3rd. // 'M': 1 or 2 digit month, 1 through 12 // 'D': 1 or 2 digit day, 1 through 31. inputDateFormat: 'MM/DD/YYYY', // Using a token system, set a specific date string format to be read out to screen reader users audibleDateFormat: 'D, dddd MMMM YYYY', // Allow a date that isn't today to be set as the initial date. If unset, this value is initialised to today's date initialDate: new Date(), // Disable weekdays from selection disableWeekdays: false, // Disable weekends from selection disableWeekends: false, // Set positive or negative offset for differing column arrangements, or 0 for none wdOffset: 0, // Set CSS positioning calculation for the calendar // Set to 0 to disable auto positioning autoPosition: 9, // Customize with positive or negative offsets offsetTop: 0, offsetLeft: 0, // Set class for the calendar container className: 'calendar', // Set custom CSS styling for the calendar container when rendered cssObj: { position: 'absolute', zIndex: 1 }, // Choose a different insertion point in the DOM; must be a DOM node; defaults to the triggering element if not specified. targetObj: null, // Choose a different focus element in the DOM for CSS autoPositioning; may be a DOM node or CSS Selector; defaults to the triggering element if not specified. posAnchor: '', // Reset date to the current calendar date every time the date picker opens resetCurrent: false, // Configure the Comments tooltip pane comments: { role: 'Comment', autoPosition: 1, offsetTop: 0, offsetLeft: 0, className: 'commentTooltip' }, // Configure the editor form pane editor: { // Choose to show the form, defaults to false show: false, // Set the section name, and the Edit button text role: 'Edit', autoPosition: 6, offsetTop: 0, offsetLeft: 0, className: 'commentAdd', // Set the Save button text action1: 'Save' }, // Condense the year display by removing the year nav buttons. Requires the Calendar Module version 1.25 or greater. condenseYear: false, // Manually configure the calendar using AJAX or a customization script ajax: function(dc, save){ // 'save' is true when closing the Editor, false otherwise for fetching content when the calendar is opened. // If save is false, execute load script if (!save){ // Optionally load custom values into the dc.range associative array. // And optionally prevent this script from running again // dc.stopAjax = true; // Then open the calendar after processing is finished dc.open(); } else{ // Otherwise do something with the newly saved values within the dc.range associative array. } } }
Programmatic Control
Every Date Picker is registered as an AccDC Object, the ID of which matches the ID string declared in the first parameter of the invocation statement.
This also makes it possible to control the calendar programmatically using JavaScript, like so:
var dc = $A.reg['UniqueCalendarId']; // Which you can then open dc.open(); // Or close dc.close(); // All other AccDC API properties and methods can be applied here as well.
Triggering Element Requirements
Regarding the triggering element, you should always use an active element for this purpose to ensure accessibility for both screen reader and keyboard only users.
Within the Coding Arena samples, these are standard image links (A tags with an Href attribute and an embedded IMG tag with an informative Alt attribute). However, you can use whatever type of triggering element you wish, a standard link, button, or image link, with any type of styling. There must be an active element as a triggering element though, to ensure accessibility.
Styling
The sample calendars in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.
You can change the styling however you wish to fit the layout of any UI, and the calendars will still be accessible to both screen reader and keyboard only users regardless.
Simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled calendar will be accessible.
Bootstrapping
Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.
The calendars within the Bootstrap folders are configured using HTML5 "data-"
attributes within the HTML markup.
When the Bootstrap Module ("accdc_bootstrap.js") is executed, it parses the newly loaded DOM, recognizes the class accCalendar
,
then configures the same module declaration as previously described using these HTML5 attributes.
Available HTML5 attributes for the triggering element:
- data-name : The name value for the calendar picker. The Name attribute of the accompanying text field must match the
data-name
attribute value. The selected date will then be inserted into the text field. (Must be on the triggering element.)
Additional HTML5 attributes can be added to enhance functionality by editing the file "accdc_bootstrap.js".
Required attributes:
- name="whatever" : The Input field name attribute that matches the value of
data-name
. (Must be on the Input field withtype="text"
) - class="accCalendar" : The bootstrap class name that specifies an accessible calendar picker. (Must be on the triggering element.)
- id : The unique ID of the element. This value is also registered as the ID of the calendar AccDC Object, making it possible to invoke the object programmatically. (Must be on the triggering element.)
Implementation Notes
The date string format is configurable within the callback function, or within the "accdc_bootstrap.js" module if bootstrapped.
The variables to reference are as follows:
var weekDay = dc.range.wDays[dc.range.current.wDay].lng; // 'Friday' var monthName = dc.range[dc.range.current.month].name; // 'November' // or (dc.range.current.month+1) = numerical month string var monthDay = dc.range.current.mDay; // '30' var year = dc.range.current.year; // '2012'
The returned values will reflect the date selected.
The ARIA Listbox is a simple concept, turned into a powerful component.
Expected behaviors: ARIA Listboxes should only receive one tab stop, the Up/Down/Home/End keys should move focus appropriately, and every listbox and listbox option should be explicitly labeled.
The Listbox Module automates these processes by adding all related event handlers and managing all related rendering procedures.
- Basic simulated Listbox control with ARIA
role=listbox, role=option, aria-posinset, aria-setsize, aria-selected, aria-label
, andaria-owns
:
Coding Arena/ARIA Listboxes/Standard/demo.htm - Multiselectable simulated Listbox control with ARIA
role=listbox, role=option, aria-posinset, aria-setsize, aria-selected, aria-label, aria-multiselectable
, andaria-owns
:
Coding Arena/ARIA Listboxes/Multiselect/demo.htm - Basic popup simulated Listbox control with ARIA
role=listbox, role=option, aria-posinset, aria-setsize, aria-selected, aria-label
, andaria-owns
:
Coding Arena/ARIA Listboxes/Popup Listbox (Internal Content)/demo.htm - Dynamic multiselectable simulated Listbox control with ARIA
role=listbox, role=option, aria-posinset, aria-setsize, aria-selected, aria-label, aria-multiselectable
, andaria-owns
:
Coding Arena/ARIA Listboxes/Redistributable/demo.htm - Re-sortable simulated Listbox control with ARIA
role=listbox, role=option, aria-posinset, aria-setsize, aria-selected, aria-label, aria-owns, aria-grabbed
, andaria-dropeffect
:
Coding Arena/ARIA Listboxes/Sortable/demo.htm
HTML Syntax

   Option One Name

   Option Two Name

   Option Three Name

Required attributes:
- role="listbox" : Specifies a Listbox group container for screen reader users. (Must be on the container element that surrounds the list items.)
- role="option" : Specifies a Listbox Option node for screen reader users. (Must be on the keyboard focusable link elements that comprise the listbox option elements.)
- ID : Specifies unique ID attribute values for both the listbox container element and all list option links.
- Href : Included within every list option A tag, this ensures keyboard accessibility.
The following attributes are handled automatically by the Listbox Module:
-
tabindex
-
aria-label
-
aria-owns
-
aria-setsize
-
aria-posinset
-
aria-selected
-
aria-checked
(if applicable) -
aria-grabbed
(if applicable) -
aria-dropeffect
(if applicable)
JavaScript
var myListbox = new $A.Listbox( $A.getEl('uniqueId1'), { // Configuration key / value mappings });
Parameters
-
The first parameter is the DOM node for the listbox container element that includes
role="listbox"
. -
The second parameter is the object literal used to configure listbox functionality using key / value map overrides.
Example:
{ // Set the initial list option node to be selected defaultIndex: 0, // Set a label for screen reader users label: 'Unique field label text', // Choose whether the Listbox is single or multiselect (multiselect is ignored when isSortable=true) isMultiselect: false, // Choose whether the Listbox is sortable isSortable: false, // Choose whether the Delete key can be used to remove list option nodes allowDelete: false, // Help messages that are announced to screen reader users when isSortable=true grabInstruct: 'Press Space to grab', dropInstruct: 'Press Space to drop', grabMsg: 'Grabbed', dropMsg: 'Moved', cancelDrop: 'Grab canceled', // Do stuff whenever the selection changes callback: function(optionNode, optionsArray){ // this.val() returns the current value of the Listbox control, a string if single-select or an array of strings if multiselect } }
Programmatic Control
Since the Listbox control is an instantiated object, all of the following public properties and methods are available:
myListbox.container; // The Listbox DOM node for the element with role="listbox" myListbox.options; // The array of list option DOM nodes that contain role="option" myListbox.index; // The array index number for the currently selected list option element (relative to myListbox.options) myListbox.grabbed; // The ID string value of the currently grabbed list option DOM node (when isSortable=true) myListbox.val(); // Returns the current value of the Listbox control: An ID string when the listbox is single-select; an array of ID strings when the Listbox is a multiselect. myListbox.val(indexValue); // Sets the current Listbox selection to the specified array index value (relative to myListbox.options) myListbox.val('IdString'); // Sets the current Listbox selection to the specified list option DOM node that matches this ID (contained within myListbox.options) myListbox.val(['IdString1', 'IdString2']); // Sets the current Listbox selection to all of the list option DOM nodes that match the ID strings in the array (when isMultiselect=true and contained within myListbox.options) myListbox.val([]); // Clears all previously 'grabbed' or 'checked' list options if either isSortable or isMultiselect is set to True. myListbox.rem(indexValue); // Removes the list option DOM node from myListbox.options at the specified array index value, and returns the removed A tag DOM node. myListbox.rem('IdString'); // Removes the list option DOM node from myListbox.options by matching the ID, and returns the removed A tag DOM node. myListbox.rem(['IdString1', 'IdString2']); // Removes the array of list option DOM nodes from myListbox.options by matching the IDs, and returns the removed A tag DOM nodes in an array. myListbox.add(A-TagDOM-Node); // Adds a new list option to the Listbox. (Must be an A tag DOM node that includes a unique ID attribute value, an Href attribute for keyboard accessibility, and innerText to set the screen reader accessible label text) myListbox.add([A-TagDOM-Node1, A-TagDOM-Node2]); // Adds an array of new list options to the Listbox. (Must include A tag DOM nodes that include a unique ID attribute value, an Href attribute for keyboard accessibility, and innerText to set the screen reader accessible label text) myListbox.activate.apply(listOptionDOM-Node); // Programmatically activate the 'grab' or 'check' functionality for a specific list option DOM node (within myListbox.options when either isSortable or isMultiselect is set to True). The single parameter for this statement must consist of the A tag DOM node for the list option that you wish to activate. This simply performs a toggle action on the specified option, and does not specify a particular state.
Styling
The sample listboxes in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like. This is demonstrated within the "Shell" folders, where there is no CSS styling for the listbox. This is also useful as a practice template for trying out different styling designs with custom content.
When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled listbox will be accessible.
Implementation Notes
All list option elements must be marked up as links (A tags with an Href attribute) to ensure backwards compatibility and graceful degradation. These are the only elements that will receive keyboard focus.
All list option elements, as well as the listbox container, must include unique ID attribute values.
In the case of the list option elements, the ID is used as the value of the Listbox control, so when an item is activated, the value of the Listbox will be returned as the ID value for the active A tag. For standard Listboxes, this is the ID of the currently selected list option as a string. E.G "uniqueId2" For Multiselect Listboxes, This is an array of the ID strings of the currently checked list options. E.G ["uniqueId2", "uniqueId4"]
An innerText label for each A tag must be included to ensure accessibility for screen reader users, though you may position this text offscreen to hide it visually if desired.
Alternatively, you may also include IMG tags within the A tags to form image links. When an IMG tag includes an informative Alt attribute, this text is also included as part of the list option label for screen reader users.
If a background image is used instead however, then there must be an innerText label, even if positioned offscreen, to ensure accessibility for screen reader users.
All list option label text must be unique, to prevent confusion for screen reader users.
An ARIA Menu is a simple control type that can easily be made accessible.
Expected behaviors: A keyboard accessible mechanism opens the menu, the arrow keys are used to browse available menu items or open and close submenus, pressing Tab will close all open menus, and pressing Escape will close the currently open menu.
ARIA menus can be implemented in two ways, horizontally or vertically. This has nothing to do with what they look like, since the CSS styling can be set to whatever you like, but rather, refers to the keyboard interaction model for each menu.
A vertical menu is navigated using the Up and Down arrow keys to scroll through menu items, and Left and Right are used to close or open submenus.
A horizontal menu is navigated using the Left and Right arrow keys to scroll through menu items, and Up and Down are used to close or open submenus.
You can optionally set different interaction models for specific menus or submenus depending on how the menu is visually presented, so that the behavior properly fits the UI design.
Additionally, a menu may be triggered using either the left or right click, with accompanying behaviors for each.
A left click menu often uses a link or button as the triggering element, and also supports the Down arrow, Space, and Enter keys to invoke the menu from the keyboard.
For more complex controls, such as interactive ARIA Widgets that include their own functionality attached to the arrow keys and the left click handler, the right click menu may be used, which also supports the Shift+F10 and Application keystrokes for keyboard support.
The right click menu may also be used on the Body element to present a customized page wide context menu that has no dedicated triggering element.
The Menu Module automates these processes by adding all related event handlers and managing all related rendering procedures.
- Button: Basic left-click horizontal popup Menu control with ARIA
role=menubar, role=menuitem, aria-posinset, aria-setsize, aria-haspopup, aria-owns
, androle=application
:
Coding Arena/ARIA Menus/Horizontal (Internal Content)/demo.htm - Button: Basic left-click vertical popup Menu control with ARIA
role=menu, role=menuitem, aria-posinset, aria-setsize, aria-haspopup, aria-owns
, androle=application
:
Coding Arena/ARIA Menus/Vertical (Internal Content)/demo.htm - Body: Basic page wide right-click Popup Menu control with ARIA
role=menu, role=menuitem, aria-posinset, aria-setsize, aria-haspopup, aria-owns
, androle=application
:
Coding Arena/ARIA Menus/Variation Body Element With Right Click/demo.htm - ARIA Textbox: Basic right-click Popup Menu control with ARIA
role=menu, role=menuitem, aria-posinset, aria-setsize, aria-haspopup, aria-owns
, androle=application
:
Coding Arena/ARIA Menus/Variation Simulated Edit With Right Click/demo.htm - Standard Textareas: Basic right-click Popup Menu control with ARIA
role=menu, role=menuitem, aria-posinset, aria-setsize, aria-haspopup, aria-owns
, androle=application
:
Coding Arena/ARIA Menus/Variation Standard Edits With Right Click/demo.htm - ARIA Tabs: Complex right-click Popup Menu control with ARIA
role=menu, role=menuitem, aria-posinset, aria-setsize, aria-haspopup, aria-owns
, androle=application
:
Coding Arena/ARIA Menus/Variation ARIA Tabs With Right Click/demo.htm - ARIA Tree: Complex right-click Popup Menu control with ARIA
role=menu, role=menuitem, aria-posinset, aria-setsize, aria-haspopup, aria-owns
, androle=application
:
Coding Arena/ARIA Menus/Variation ARIA Tree With Right Click/demo.htm
HTML Syntax
Basic menu structure with no submenus:

  Menu Item One Name

  Menu Item Two Name

  Menu Item Three Name

Basic menu structure with nested submenus:

  Subfolder Menu Item One Name (Level 1)

  Subfolder Submenu Item One Name (Level 2)

  Submenu Item One Name (Level 3)

  Submenu Item Two Name (Level 2)

  Menu Item Two Name (Level 1)

The HTML menu syntax is flexible, and may consist of UL tags, OL tags, DIV tags, or any other combination, as long as the container element includes a unique ID, as well as each menu item tag.
For simplicity, these have been marked up as list elements, which is generally preferable since it includes native screen reader support for nested lists. Also, the use of standard A tags with an Href attribute ensures keyboard accessibility across all Assistive Technologies for graceful degradation.
You may also use additional HTML markup within the menu item links for formatting purposes (such as SPAN tags), as long as you don't add additional active elements such as clickable images. The only actionable element should be the menu item link, and nothing else.
Submenus are mapped by combining the ID attribute value of the container element, with the ID attribute value of the submenu link. The two combined point to the full ID attribute value of the associated submenu container element.
For example, notice the ID value on the top level menu OL tag above is id="uniqueId1"
, and the ID of the first Subfolder
A tag within that structure is id="-uniqueId2"
.
When you combine the two ("uniqueId1-uniqueId2"
), notice that this directly points to the submenu OL tag as its ID attribute value.
You can experiment with this in the Coding Arena "Shell" folders, where the same code is used.
Important: Don't add any ARIA attributes to the markup, and don't add tabindex attributes. All of these are handled automatically when the menus are rendered.
If the menu constructs are contained within the same page, they must be contained within a container element that has an ID attribute. This is used by the setup function to confine the parsing query to this node only.
Example:

 ...

The following attributes are handled automatically by the Menu Module:
-
role="menubar"
(horizontal) -
role="menu"
(vertical) -
aria-owns
-
tabindex
-
role="menuitem"
-
aria-posinset
-
aria-setsize
-
aria-haspopup
HTML5 attributes that can optionally be added to the menu list container markup:
- data-horizontal="true"/"false" : Sets or unsets a horizontal flyout menu where the Left and Right arrow keys will be used to navigate menu item nodes, and Up and Down will be used to close or open submenus. This temporarily overrides the interaction model set within the JavaScript declaration statement.
- data-offsetleft="number" : Specifies a positive or negative offsetLeft value that will be applied to the menu after it is rendered.
- data-offsettop="number" : Specifies a positive or negative offsetTop value that will be applied to the menu after it is rendered.
- data-autoposition="number between 0 and 12" : Specifies a custom
autoPosition
value that will control where the menu is visually positioned relative to the triggering element.Value Definitions:
- 0: Disabled
- 1: Above/Center/Left Edge Aligned
- 2: Above/Right/Right Edge Aligned
- 3: Level/Right/Right Edge Aligned
- 4: Below/Right/Right Edge Aligned
- 5: Below/Center/Left Edge Aligned
- 6: Below/Left/Left Edge Aligned
- 7: Level/Left/Left Edge Aligned
- 8: Above/Left/Left Edge Aligned
- 9: Level/Center/Left Edge Aligned
- 10: Above/Center/Right Edge Aligned
- 11: Level/Center/Right Edge Aligned
- 12: Below/Center/Right Edge Aligned
Example:

 ...

JavaScript
$A.setMenu( 'CSS-SelectorForTriggeringElement' , 'LocalePathOrContainerID' , 'TopLevelMenuID' , callbackFunction(ev, dc){ // Do something every time a menu item link node is clicked } , areMenusInTheSameDoc? , contextDOM-Node , { // Configure key / value mapping overrides });
Parameters
-
Parameter 1: The triggering element CSS Selector
This points to the triggering element link or button that you want to use as the menu triggering element. For instance, the CSS Selector"a.button"
points to the A tag withclass="button"
for this purpose. Multiple triggering elements that open the same menu may be specified using one CSS Selector. -
Parameter 2: The Locale Path or Container ID
When menus are contained within an external HTML file, this string value is the relative file path, such as "files/menus.html".
When menus are contained within the same page, this string value is the ID attribute of the container element where all of the menu tags are located, such as"hiddenDivId"
. -
Parameter 3: Top Level Menu ID
This string is the top level menu ID attribute value, such as"uniqueId1"
, which is used to specify which menu will be opened first when the triggering element is activated. -
Parameter 4: The Callback Function
This is where you can set specific functionality to occur whenever a menu item link is activated, whether this is to navigate to another page, or to perform another client side action.
When declared, two arguments are passed to the function, first is the event object, and the second is the AccDC Object for the currently open menu object.
Usingthis
within the function will reference the DOM node for the activated element, which is useful if mapping the ID attribute to a particular action.dc.top.triggerObj
(where dc is the AccDC Object) provides the DOM node for the original triggering element that first opened the menu. -
Parameter 5: Are Menus within the Same Doc
A Boolean (true or false), that specifies whether the script should process the Locale parameter as an internal or external resource locator.
If menu markup is contained within an external HTML file, set this to false, otherwise set to true. -
Parameter 6: The Context DOM Node
This is the DOM node that will be used to confine the parsing query.
Typically this is set to document, since all of the IDs are relative to this location.
However, this parameter gives you the ability to reference iFrame documents instead if desired. -
Parameter 7: The Config Object
This is a key / value mapping of overrides that can be used to customize the element types of menu container and menu item elements, the class names for each, the default keyboard interaction model, the default auto positioning if desired, plus additional AccDC API overrides if desired.Example:
{ // Enable right click functionality // Automatically configures keyboard support using Shift+F10 and the Applications key // When set to false, the Enter, Space, and Down arrow keys are supported in addition to onclick rightClick: true, // Default: false // Set the accessible help description that will be announced for screen reader users // Only applicable when rightClick is set to true // Will automatically clear on touch screen devices to prevent confusion rightClickText: 'Press Shift+F10 or the Applications key to open the popup menu', // Set the main container class, (which will surround the menu as a Div tag when rendered) containerClass: 'menu', // Specify the menu tag name in the markup menuTag: 'ol', // Specify the menu class name on the above tag in the markup menuClass: 'menu', // Specify the active element that will be used as each menu node // Important, if nesting A tags within LIs, only the A tag should be used for this purpose // Active elements should never be nested. // The following tag will receive keyboard focus within the menu structure when using the arrow keys to navigate // Event bindings are also tied to this tag itemTag: 'a', // Specify the class name that indicates when a menu item opens a submenu folderClass: 'submenu', // Specify the class name that indicates when a menu item is to be triggered directly // This should not be the same as the folderClass declaration linkClass: 'link', // Specify if the menu is a flyout menu // If true, the Left and Right arrow keys will scroll the open menu // If false, the Up and Down arrow keys will scroll the open menu instead horizontal: false, // Set a default autoPosition value between 0 (disabled) and 12 autoPosition: 0, // Set custom offset values to adjust the positioning calculation // May return a positive or negative number offsetLeft: function(dc){ return 0; }, offsetTop: function(dc){ return 0; }, overrides: { // Additional AccDC API properties and methods can be applied here if desired. } }
Programmatic Control
Every menu instance is registered as an AccDC Object, the ID of which matches the ID attribute value on the menu container element.
This means that you can programmatically control each menu using JavaScript if desired, like so:
// Get a reference to the top level Menu AccDC Object for the menu container with id="uniqueId" var dc = $A.reg['uniqueId']; // Now invoke the object dc.open(); // Or close it dc.close(); // All other AccDC API properties and methods can be applied here as well.
Additionally, when a menu is attached to a triggering element, the custom handler popupmenu
is attached to that element.
To support both standard and touch device usage as part of responsive design, a specially displayed icon (typically referred to as a Hamburger icon) is often displayed conditionally on touch screen devices to allow for context menus to be actionable [ Reference ]
Such an icon can be programmatically configured to open the popup menu attached to the triggering element by manually triggering the popupmenu
event on that element.
// Detect if running on a touch device if ('ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0){ // Unhide the hamburger icon and attach an onclick handler $A.bind($A.remClass(hamburgerIconElement, 'hidden'), 'click', function(ev){ // Trigger the menu attached to the original triggering element $A.trigger(originalTriggeringElement, 'popupmenu'); ev.stopPropagation(); // Important to prevent bubbling and auto closing ev.preventDefault(); }); }
Similarly, a currently open menu can be programmatically closed by triggering the closepopupmenu
event on the triggering element.
// Close the menu attached to the original triggering element $A.trigger(originalTriggeringElement, 'closepopupmenu');
When aria-disabled="true"
is programmatically set on any menu item node after rendering, it will automatically
be disabled within the menu, so that disabled submenus will not open when clicked or arrowed to, and custom handling for non-submenu
links can then be processed individually within the click callback.
Triggering Element Requirements
When a custom menu is applied to the Body element, no triggering element is required.
All other usages for custom popup menus require the use of a keyboard focusable active element that includes a valid active element role, which may consist of any native active element such as a standard link or form field, or a keyboard accessible interactive ARIA Widget type.
Valid interactive ARIA Widget roles include:
- button
- checkbox
- columnheader
- combobox
- grid
- gridcell
- link
- listbox
- option
- radio
- rowheader
- slider
- spinbutton
- tab
- textbox
- tree
- treegrid
- treeitem
[ Reference ]
Styling
The sample menus in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like. This is demonstrated within the "Shell" folders, where there is no CSS styling for the menu. This is also useful as a practice template for trying out different styling designs with custom content.
When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled menu will be accessible.
Bootstrapping
Bootstrapping is designed to handle common control types that span multiple pages with similar setup configurations.
The menus within the Bootstrap folders are configured using HTML5 "data-"
attributes within the HTML markup.
When the Bootstrap Module ("accdc_bootstrap.js") is executed, it parses the newly loaded DOM, recognizes the class "accMenu"
,
then configures the same module declaration as previously described using these HTML5 attributes.
Available HTML5 attributes for the triggering element:
- data-src : The resource path and pointer to the ID attribute of the top level menu list. If pointing to a menu list within the same document, only the ID attribute should be included here.
- data-internal : The ID attribute of the container element for all menu lists within the same document.
If
data-src
is set to an external source,data-internal
should be blank or not included. - data-containerclass : The class name that will be added dynamically to the surrounding Div tag for each menu group when rendered.
"menu"
is set by default if no value is specified. - data-menutag : The tag name for the container element that contains all menu item tags. All menu item tags must be contained within this container element, even if they are not first level child nodes. "ol" is set by default if no value is specified.
- data-menuclass : The shared class name that is contained within every menu container element. All menu tags specified by
data-menutag
must include this class name."menu"
is set by default if no value is specified. - data-menuitemtag : The shared tag name that specifies all menu item tags. All menu item tags must be contained within the container element specified
by
data-menutag
, even if they are not first level child nodes."a"
is set by default if no value is specified. - data-menufolderclass : The shared class name that is contained within every menu tag that opens a submenu.
"submenu"
is set by default if no value is specified. - data-menulinkclass : The shared class name that is contained within every menu tag that does not open a submenu.
"link"
is set by default if no value is specified. - data-flyout="true" : Specifies a horizontal flyout menu where the Left and Right arrow keys will be used to navigate menu item nodes, and Up and Down
will be used to close or open submenus. If
data-flyout
is not included within the markup, the default vertically oriented keyboard assignments will be applied automatically.
Additional HTML5 attributes can be added to enhance functionality by editing the file "accdc_bootstrap.js".
Required attributes for the triggering element:
- class="accMenu" : The bootstrap class name that specifies an accessible menu triggering element.
Implementation Notes
The lists can be set to any tag, such as OL, UL, etc, as long as this is specified in the menuTag property within the JavaScript declaration statement or within the data-menutag attribute on the triggering element if Bootstrapped.
The same is true for the menu item nodes, which is specified using the menuItemTag property in the JavaScript
declaration statement, or within the data-menuitemtag
attribute on the triggering element if Bootstrapped.
Menus and submenus may be nested or broken out into separate lists within the markup if desired, as long as they are all contained within the same top level container element specified by ID within the JavaScript invocation statement, or within the data-internal attribute on the triggering element if Bootstrapped.
All menu container elements and menu item nodes must include unique ID attributes.
Submenus are mapped by combining the ID attribute of the top level menu container ID and the submenu pointer link ID, which, when combined, points to the ID of the referenced submenu container.
All menu item nodes must include innerText
to ensure accessibility for screen reader users.
Don't include any ARIA attributes within the menu markup, since this is handled automatically by the Menu module.
ARIA Radio buttons provide a means for rendering standard links as a radio button group.
Expected behaviors: Only one radio button should receive focus in the tab order, regardless whether one or no radio button in the group is selected. If a radio button is selected, only the currently selected radio button should appear in the tab order. The arrow keys should move focus to the next or previous radio button in the group, and the act of moving to that radio button should automatically select it.
The Radio Button Module automates these processes by adding all related event handlers and managing keyboard focus appropriately.
- Basic simulated Radio controls with ARIA
role=radiogroup, role=radio, aria-posinset, aria-setsize, aria-checked
, andaria-owns
:
Coding Arena/ARIA Radio Buttons/ARIA Radio Buttons/demo.htm
HTML Syntax

   Radio One Label Text

   Radio Two Label Text

   Radio Three Label Text

Markup requirements
- The Radio container element must include the attribute
role="radiogroup"
. - All radio option nodes must include the attribute
role="radio"
. - Both the Radio container element and all radio option nodes must include unique ID values. The current value for a Radio Control is the ID attribute of the currently selected radio button.
- The innerHTML for each radio option node must contain a textual label, which may be positioned offscreen to hide it visually if desired.
This textual label is critical so that screen reader users will be able to identify the purpose of the radio button.
If the textual label is included within another tag (such as a Span tag) for formatting purposes, aria-labelledby must be used to explicitly associate the label text with the element that includes role="radio" by referencing its ID.
Additionally, the textual label must be included within the opening and closing tags of the element withrole="radio"
. - If using an A tag, an href attribute is required to ensure keyboard accessibility.
- Images may also be used within radio option nodes if desired.
If an image is present however, it should include the attributealt=""
to hide it from screen reader users.
An image with a textual Alt value won't be reliably announced as the radio button label in all browsers, which is whyalt=""
is used to hide it from screen reader users.
A textual label must be used instead to ensure the highest level of accessibility for the highest percentage of people.
To add a tooltip for sighted mouse users, use the Title attribute on the IMG tag instead.
The value within the Title attribute must match the text contained within the textual label however, especially when the textual label is positioned off screen to hide it visually. (This will ensure equal accessibility for all user types)
The following attributes are handled automatically by the Radio Button Module:
-
tabindex
-
aria-owns
-
aria-setsize
-
aria-posinset
-
aria-selected
-
aria-checked
JavaScript
var myRadioGroup = new $A.RadioGroup( 'radiogroupId' , 'CSS Selector for All Radio Elements' , DefaultIndexValue , 'Optional Legend Text' , callbackFunction(selectedRadioNode, radiosArray){ // Do something whenever a radio is selected // this.value is the ID value of the newly selected radio element } );
Parameters
-
Parameter 1: The ID attribute of the radio group container. (This is the element with
role="radiogroup"
) -
Parameter 2: The CSS Selector that identifies all elements with
role="option"
(all of which must be contained within the container specified in parameter 1) -
Parameter 3: The array index of the radio button that you want to be selected by default when instantiated.
(Simply pass -1 to specify that no radio button should be selected by default) -
Parameter 4: The shared legend text that will be announced to screen reader users whenever a radio button group receives initial focus.
The legend text will be announced in addition to the textual label for the radio button.
To use a visually displayed legend instead (as demonstrated within the Coding Arena samples), usearia-labelledby
on the element withrole="radiogroup"
, and pass "" to this parameter to skip it. -
Parameter 5: The callback function that will be executed whenever a new radio button is activated.
Programmatic Control
When a radio button grouping is instantiated as a new Radio Group Control, all of the following public properties and methods are available:
('myRadiogroup'
refers to the variable instance name)
myRadiogroup.radios; // The array of all radio option DOM nodes myRadiogroup.index; // The array index of the currently selected radio option myRadiogroup.value; // The string ID attribute value of the currently selected radio option myRadiogroup.set('radioId'); // Sets the radio option with id="radioId" myRadiogroup.set(arrayIndex); // Sets the radio option at the specified array index (relative to myRadiogroup.radios)
Styling
The sample radios in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like. This is demonstrated within the "Shell" folders, where there is no CSS styling for the radio group. This is also useful as a practice template for trying out different styling designs with custom content.
When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled radio group will be accessible.
ARIA Sliders are used to present adjustable values for users, and can easily be made accessible.
Expected behaviors: The slider should have only one tab stop in the tab order, the arrow keys should move the slider in single value increments, PageUp/PageDown should move the slider in 10% increments, Home/End should move the slider to the beginning or end, and the slider should be draggable using the mouse as usual.
The Slider Module automates these processes by adding all related event handlers and managing keyboard focus appropriately.
- Horizontal Slider control with ARIA
role=slider, aria-label, aria-valuemin, aria-valuemax, aria-valuenow, aria-valuetext
, andaria-orientation
:
Coding Arena/ARIA Sliders/Horizontal/demo.htm - Vertical Slider control with ARIA
role=slider, aria-label, aria-valuemin, aria-valuemax, aria-valuenow, aria-valuetext
, andaria-orientation
:
Coding Arena/ARIA Sliders/Vertical/demo.htm
HTML Syntax

 0%

 100%

Important: The first parentNode container of the draggable slide element must be relatively positioned to set this as
the offsetParent. In the above markup, this is the Div tag with class="slide clearfix"
.
Also, notice that aria-hidden="true"
is used on the Min and Max container tags.
Since these values will be provided to screen reader users as part of the ARIA Slider Control, having them announced during navigation
would only repeat the same information twice, which is unnecessary. So aria-hidden
is used to remove them from the Virtual Buffer for screen reader users.
The next step is to use CSS to set the width and height of the slider, which you can see examples of in the Coding Arena samples. This is important, because when the Slider Control is instantiated, it will use these offsets to configure the positioning calculations and map them to related keyboard commands.
The following attributes are handled automatically by the Slider Module:
-
tabindex
-
aria-label
-
role="slider"
-
aria-valuemin
-
aria-valuemax
-
aria-valuenow
-
aria-valuetext
-
aria-orientation
JavaScript
$A.setSlider('handleId', { // Configure key / value mappings });
Parameters
-
The first parameter is the ID of the element that will be made draggable, which will then be morphed into an AccDC Object. E.G
"handleId"
The markup structure will slightly change at this point, since an extra DIV will then surround the element withid="handleId"
. -
The second parameter is where all of the slider configuration is set.
Example:
{ // Set the role text that is conveyed to screen reader users role: 'Slider', // Set a minimum value min: 0, // Set a maximum value max: 100, // Set the start value now: 50, // Is a vertical slider? vertical: false, // Set the hidden link text for graceful degradation // This should reflect the purpose of the slider degradeLbl: 'Manually choose a percentage', // Return the string that will act as the ARIA Slider label for screen reader users // This should reflect the purpose of the slider ariaLabel: function(dc){ return 'Choose a percentage between 0 and 100'; }, // Return the string that will act as the textual notification for screen reader users // This is automatically announced every time the slider is moved valueText: function(dc, val){ return val + '%'; }, // Set the action to occur whenever the value changes onDrag: function(ev, dd, dc, val){ // ev is the standard event object // dd is the custom drag event object // dc is the AccDC Object for the Slider // val is the current value of the slider }, // Set the class name for the surrounding Div, which automatically surrounds the drag handle element className: 'handleWrapper' }
Programmatic Control
After a Slider Control is instantiated, it can be controlled programmatically using its ID, which matches the ID attribute value of the drag handle (passed as the first parameter in the invocation statement).
Example:
// Get a reference to the Slider AccDC Object using its ID, which matches the handle elements ID attribute var dc = $A.reg['handleId']; // Get the current slider value var currentVal = dc.config.now; // Assign a new slider value dc.config.now = currentVal + 10; // Apply the change dc.set.apply(dc);
Styling
The sample sliders in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.
When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled sliders will be accessible.
Implementation Notes
Simply use CSS to set the size of the slider, and the height and width of the container element, and then the slider will configure itself using these offsets.
Since repetitive labels are used, and the textual slider icon has no value for screen reader users, aria-hidden="true"
is used to hide them from screen reader users.
Don't include any other ARIA attributes however, the Slider module handles this automatically.
The slide icon can be changed to anything, or an image or CSS background image can be used instead, and the styling can be configured for any layout, and it will still be accessible for screen reader and keyboard only users.
VoiceOver instructions for use on iOS touch screen devices:
When VoiceOver is used on iOS touch screen devices, VoiceOver instructs the user to swipe up and down with one finger to adjust the slider value, which is incorrect. (Last verified on 04/07/2013)
Instead, do the following:
- Use one finger and double tap the slide icon, and keep your finger pressed down on the second tap.
- Wait until you hear a slight noise, then slide your finger in the direction that you wish to move the slider.
- Then lift your finger to release the slider.
Credit goes to David Hilbert Poehlman for providing VoiceOver pass-through technique instructions.
The Toggle Control is a multipurpose control type, that covers checkboxes, toggle buttons, switches, and even simulated links and buttons.
Expected behaviors: The general behavior of a Toggle control is to receive keyboard focus in the tab order regardless of the active select state, to be toggleable or actionable by pressing the Spacebar or by pressing Enter on the control, and to be toggleable or actionable by clicking it as usual.
The Toggle Module automates these processes by adding all related event handlers.
- Simulated Checkbox controls with ARIA
role=checkbox
, andaria-checked
:
Coding Arena/ARIA Toggles, Checkboxes, Links, and Buttons/ARIA Checkboxes/demo.htm - Simulated Switch controls with ARIA
role=switch
, andaria-checked
:
Coding Arena/ARIA Toggles, Checkboxes, Links, and Buttons/ARIA Switches/demo.htm - Simulated Toggle Button controls with ARIA
role=button
, andaria-pressed
:
Coding Arena/ARIA Toggles, Checkboxes, Links, and Buttons/ARIA Toggle Buttons/demo.htm - Simulated Button and Link controls with ARIA
role=button
orrole=link
:
Coding Arena/ARIA Toggles, Checkboxes, Links, and Buttons/ARIA Links and Buttons/demo.htm
HTML Syntax
The HTML syntax varies depending on which type of implementation is desired, and each type has specific rules that must be observed in order to ensure the highest level of accessibility for screen reader users.
IMG
For IMG tags, the following attributes are required to ensure accessibility for the widest range of screen readers:
- aria-label : Specifies a textual label for screen reader users. (The Alt alone won't work for this purpose)
- alt="" : Hides the image from screen reader users when no tooltip is desired for mouse users.
To add a tooltip for sighted mouse users, use both the Alt and Title attributes. The text for both must match the text contained within thearia-label
attribute, so that all three are the same. This will also maximize accessibility in iOS devices using VoiceOver. - role="button" must be added for toggles,
role="checkbox"
must be added for checkboxes, orrole="switch"
must be added for switches. - A unique ID must be added for proper event binding.
Examples:

INPUT
For INPUT tags with type="image"
, the following attributes are required to ensure accessibility for the widest range of screen readers:
- aria-label : Specifies a textual label for screen reader users. (The Alt alone won't work for this purpose)
- Title : Specifies a textual label for screen reader users. This must match the text contained within the aria-label attribute.
(Both the Title and aria-label attributes are required to correct differing screen reader feedback when tabbing versus arrowing down the page using JAWS.) - To add a tooltip for sighted mouse users, use both the Alt and Title attributes. The text for both must match the text contained within the aria-label attribute, so that all three are the same.
- role="button" must be added for toggles,
role="checkbox"
must be added for checkboxes, orrole="switch"
must be added for switches. - A unique ID must be added for proper event binding.
Examples:
<input type="image" role="button" aria-label="Toggle Button Label" alt="Toggle Button Label" title="Toggle Button Label" id="uniqueId3" src="icon.png" /> <input type="image" role="checkbox" aria-label="Checkbox Label" alt="Checkbox Label" title="Checkbox Label" id="uniqueId4" src="icon.png" /> <input type="image" role="switch" aria-label="Switch Label" alt="Switch Label" title="Switch Label" id="uniqueId4" src="icon.png" />
Container Elements
For all other container elements that support innerHTML such as DIVs and SPANs, the following attributes and rules are required to ensure accessibility for the widest range of screen readers:
- Inner Text : Specifies a textual label for screen reader users. This may be visible or positioned using
offscreenText
. - No Embedded Active Elements : Don't embed any other active elements, including mouse clickable images, links, or anything else that needs to be activated separately. (The only actionable element should be the element with role="button" or role="checkbox".)
- To add a tooltip for sighted mouse users, use the Title attribute. This must match the text contained within the innerText label.
- role="button" must be added for toggles,
role="checkbox"
must be added for checkboxes, orrole="switch"
must be added for switches. - A unique ID must be added for proper event binding.
Examples:

  Toggle Button Label

  Checkbox Label

(The element with the valid role will automatically be made focusable.)
The following attributes are handled automatically by the Toggle Module:
-
tabindex
-
aria-checked
(if applicable) -
aria-pressed
(if applicable)
JavaScript
var myToggle = new $A.Toggle('uniqueId', { // Configure key / value mappings });
Parameters
- The first parameter is the ID attribute value of the element that will become actionable.
- The second parameter is the key / value map that configures specific functionality.
Example:
{ // Disable ARIA // (only for simulated Checkboxes and Toggle Buttons, leave out otherwise) noARIA: true, // Disable toggling // (only for ARIA Links and Buttons, leave out otherwise) noToggle: true, // Set the initial state // (only for simulated Checkboxes and Toggle Buttons, leave out otherwise) state: false, // Declare a callback to run every time the state changes callback: function(state){ // 'state' is the proposed state change, true or false // 'this' is the triggering element // Return true to accept the ARIA state change, or false to prevent return true; } }
Programmatic Control
After a Toggle control is instantiated, the following public properties and methods are available:
myToggle.state; // Reflects the current select state of the toggle (true or false) myToggle.set(Boolean); // Set the Toggle with the specified state (true or false)
Styling
The samples in the Coding Arena are styled to look a certain way for the demo, but it doesn't actually matter what they look like.
When applying new styles, simply ensure that sufficient color contrast is observed for low vision users, and a focus outline clearly shows which elements have focus, and your newly styled checkbox, button, or switch will be accessible.
An ARIA Tree is a complex control type that requires a lot of synchronizing to make accessible.
The reasons why: If the right ARIA attributes are not applied to the correct DOM nodes that receive keyboard focus, and if the parent child ID associations are not properly mapped and maintained, and if tree nodes are not labeled properly using the correct ARIA attributes, and if the tree contains any other active elements that are not part of the ARIA Tree structure, then the ARIA Tree and its contents will not be accessible for screen reader users.
Currently, a large part of this is the result of unequal support by screen reader manufacturers. For example, even though
the ARIA specification states that role="document"
can be used to embed additional content panels within specific widgets such
as this, doing so will result in content panels that are inaccessible using JAWS in both IE and Firefox. (Verified in JAWS 12, 13, and 14)
Nevertheless, the Tree Module automates these processes accessibly by adding all related event handlers and managing all related rendering procedures using an external XML file for configuration.
- Tree control with ARIA
role=tree or role=group, aria-label, role=treeitem, aria-expanded, aria-selected, aria-level, aria-posinset, aria-setsize
, andaria-owns
:
Coding Arena/ARIA Trees/Tree (External XML)/demo.htm - Shell Tree control with no CSS, ARIA
role=tree or role=group, aria-label, role=treeitem, aria-expanded, aria-selected, aria-level, aria-posinset, aria-setsize
, andaria-owns
:
Coding Arena/ARIA Trees/Tree (External XML Shell)/demo.htm
HTML Syntax

XML Syntax
<?xml version="1.0" encoding="UTF-8" ?> <tree> <branch id="uniqueId0-1" name="Branch Link Name for id=uniqueId0-1"> <leaf id="uniqueId0-1-1" name="Leaf Link Name for id=uniqueId0-1-1"></leaf> </branch> <leaf id="uniqueId0-2" name="Leaf Link Name for id=uniqueId0-2"></leaf> </tree>
The above XML markup results in the following HTML structure when rendered: