jquery.a11yTree

A very lightweight and uninvasive jQuery plugin that transforms an HTML tree of nested unorded lists into an expanding and collapsing tree that's universally accessible.

GitHub Project

The Idea

Many tree implementations don't include the functionality people using assistive technologies depend on, or are just more complex than what's needed. I also wanted to keep the amount of added classes to a bare minimum by relying on HTML semantics and WAI-ARIA roles and attributes.

Inspirations

DynaTree and Fancytree jQuery plugins
They're great—I just wanted something simpler, and less invasive to the the original DOM.
(Not so) Simple ARIA Tree Views and Screen Readers
This is a great article that breaks down all of the ARIA roles and the additional semantics ARIA provides to a document.
You can also read more information about HTML and ARIA at One of Many Reasons WAI-ARIA Is Awesome...More Semantics.

Navigation

a11yTree was built with universal web accessibility in mind. So, not only does it provide the typical mouse navigation via toggles, it also adds keyboard navigation, and additional semantics to the markup using WAI-ARIA roles and attributes.

Mouse

The tree toggle controls are identifed with the class .at-toggle and are intended to be styled as expand and collapse controls. Handlers listening to the click event are attached to these elements.

Keyboard

The tree can be navigated via the keyboard as described below. This navigation is inspired by the example on the Using ARIA Trees WAI wiki page.
down
navigates down to the next expanded tree node
up
navigates up to the previous expanded tree node
right
expands the tree node in focus if it's collapsed and has children, or navigates to the first child node of an expanded parent
left
collapses the tree node in focus if it's expanded, or navigates to the parent node
enter
expands/collapses the current tree node in focus if it has children
home
navigates to the first node in the parent tree
end
navigates to the last expanded node in the tree

WAI-ARIA

The following ARIA roles and attributes add even more semantic meaning to the HTML markup which is utilized by assistive technologies, and can be used as CSS selectors as opposed to classes that don't have meaning outside of the context of your markup.
tree and group
roles that identify the parent tree ul and the child ul elements
treeitem
role that identifies each li as an item in the tree
aria-level
attribute applied to each li element to identify which nesting level it belongs to
aria-expanded
attribute applied to each li element that has children—this is set to true when the child list is expanded
aria-selected
attribute applied to each li element and set to true when the item is navigated to—only one item in the entire tree can be identified as selected at once
aria-activedescendant
attribute applied to parent tree ul element and set to the id of the li element currently identified as selected
aria-labelledby
attribute applied to each ul element and set to the id of the text/label container of the list

Using a11yTree

While a11yTree can be configured to insert toggle controls and doesn't require labels, being unobtrusive, uninvasive, and universally accessible are some of the goals of a11yTree. So, ideally, you're starting with a set of nested unordered lists with toggle controls and labels as shown below:

a11yTree example

  • parent 1
    • child 1
      • grandchild 1
      • grandchild 2
    • child 2
  • parent 2
    • child 1
    • child 2
      • grandchild 1
      • grandchild 2
Now apply a11yTree to the parent unordered list ul element.
$('#code-example-real > ul').a11yTree({
                     treeLabelId:'tree-label',
                     toggleSelector:'i.fa',
                     treeItemLabelSelector:'.tree-item-label',
                     onCollapse:function($item) {
                      customCollapse($item);
                     },
                     onExpand:function($item) {
                      customExpand($item);
                     }
                });
And you get this:

Add multiple a11yTree trees

You can add multiple trees on the same page. However, it's important you add an id to the parent ul element—the id will be used as the id prefix for all other child elements.
  • Fender
    • Electric Guitars
      • Stratocaster
      • Telecaster
      • Jazzmaster
      • Jaguar
      • Mustang
      • Esquire
      • Jagmaster
    • Bass Guitars
      • Jazz Basses
      • Precision Bass
      • Jaguar
      • Dimension Bass
      • Telecaster Bass
    • Guitar Amps
      • Artist Signature
      • Hot Rod
      • Pro Tube
      • Super-Sonic
      • Vintage Modified
  • Gibson
    • Electric Guitars
      • Les Paul
      • SG
      • ES
      • Archtop
      • Explorer
      • Flying V
      • Firebird
    • Miscellaneous Electronics
      • Memory Cable
      • Min-ETune

Config Options

Tree and Tree Item Labels

While configuring a11yTree to be able to identify labels for the entire tree and each tree item is optional—assistive technologies won't be able to provide the best user experience. For example, without tree item labels, screen readers are extremely verbose and will end up reading aloud not just the selected node, but also all its expand children.
treeLabelId
the id of an element in the DOM that contains the label for the tree
treeItemLabelSelector
the selector for the elements in the DOM containing the label for each tree item—an id will be added to each element if one doesn't already exist, which will be used as the value of the aria-labelledby attribute for each child ul element

Toggle Controls

a11yTree is intended to provide access for all users, including mouse users. a11yTree provides the ability to work with existing toggle elements, or will inject them into the DOM for you.
toggleSelector
the selector for the toggle elements already in the DOM—the class .at-toggle will be added to each element, which will have handlers listening to the click event—your HTML may not have a toggle element, so this is optional
customToggle.html
if a toggle element doesn't already exist in the DOM, use this option to insert custom toggle HTML within the .at-toggle element—this is optional
insertToggle
if neither toggleSelector nor customToggle.html are configured an empty element with the class .at-toggle will be inserted into each li element with a nested list—setting this to false will result in a11yTree having no knowledge of toggle elements

Callbacks

Custom functionality can be configured to execute on expand and collapse of tree elements with children.
onCollapse
executed when a child list is collapsed—provides access to the parent li and the event that triggered the tree item to collapse
onExpand
executed when a child list is expanded—provides access to the parent li and the event that triggered the tree item to expand