The content on this page is associated with the Home link for Mythical University.
Navigation Treeview Example
CAUTION! Before considering use of the ARIA tree pattern for site navigation, it is important to understand:
- Correct implementation of the
tree
role requires implementation of complex functionality that is not needed for typical site navigation that is styled to look like a tree with expandable sections. - A pattern more suited for typical site navigation with expandable groups of links is the disclosure pattern.
The below example demonstrates how the
Treeview Design Pattern
can be used to build a navigation tree for a set of hierarchically organized web pages.
It illustrates navigation of a mythical university web site that is comparable to the navigation illustrated in the Example Disclosure Navigation Menu.
As noted above, the disclosure pattern is better suited for most web sites because few sites need the additional keyboard functionality required to support the ARIA tree
role.
This example relies on the browser to compute values for aria-setsize
, aria-posinset
, and aria-level
.
The ARIA specification for these properties states that browsers can, but are not required to, compute their values.
So, some browser and assistive technology combinations may not compute or report correct position and level information if it is not explicitly declared.
If testing reveals gaps in support for these properties, override automatic computation by explicitly declaring their values as demonstrated in the example of a
File Directory Treeview Example Using Declared Properties.
Similar examples include:
Example
Home
Accessibility Features
Focus Movement After Content Load
An important aspect of designing a navigation tree experience is the behavior of keyboard focus when an item in the tree is activated. If activating a tree item changes content on the page without triggering a browser page load, i.e., works like typical single-page apps, the focus position after the content load significantly affects efficiency for keyboard and assistive technology users. Accessible navigation trees typically implement one of the following two behaviors:
- Activating a tree item moves focus to the beginning of the new content, ideally a level one heading with content that matches the name of the tree item that was activated. Focusing on the heading informs screen reader users that navigation is complete and confirms the destination. This behavior is appropriate when common or important use case scenarios assume users want to start interacting with the loaded content after activating the tree item. Note: Keyboard users will need to navigate back to the navigation tree to view other pages. To optimize keyboard efficiency, design a layout that logically locates the tree immediately before the content display area in the Tab sequence.
-
Activating an item in the tree keeps focus on the activated item in the tree.
In this case, the movement of
aria-current
to the currently focused tree item informs screen reader users that navigation is complete and confirms the destination. This behavior is appropriate when common or important use case scenarios assume users are likely to need to peruse content from multiple nodes in the tree before deciding to interact with the loaded content. Note: screen reader users will need to navigate to the content to read it. In some cases, it might be possible to help screen reader users more quickly perceive the nature of the loaded content without navigating to it by referencing a portion of the content with anaria-describedby
attribute on the tree item.
The example on this page illustrates the first technique of focusing the level one heading in the newly loaded content.
Assistive Technology Support Features
- Since the tree presents a site navigation system, it is wrapped in a navigation region implemented with a
nav
element that has anaria-label
that matches the label on the tree. - To ensure assistive technology users can identify and easily locate the tree item associated with the currently displayed page:
- The
aria-current="page"
attribute is applied to the item in the tree associated with the currently displayed page. -
The tree item with
aria-current
is also the only item withtabindex="0"
. That is, when tabbing into the tree, focus always lands on the item representing the current page. - When focus leaves the tree, if the item representing the current page is in a branch that has been collapsed, that branch is expanded to ensure the current page item is both visible and exposed as active to assistive technologies.
- The
Visual design and high contrast features
- To help communicate that the arrow keys are available for navigation within the tree, a border is added to the tree container when focus is within the tree.
- To support operating system high contrast settings:
- Because transparent borders are visible on some systems with operating system high contrast settings enabled, transparency cannot be used to create a visual difference between the element that is focused an other elements. Instead of using transparency, the focused element has a thicker border and less padding. When an element receives focus, its border changes from 1 to 3 pixels and padding is reduced by 2 pixels. When an element loses focus, its border changes from 3 pixels to 1 and padding is increased by 2 pixels.
-
To ensure the arrow icons used to indicate the expanded or collapsed state have sufficient contrast with the background when high contrast settings invert colors, the CSS
currentColor
value for thefill
andstroke
properties of the SVGpolygon
element is used to synchronize the color with text content. If specific colors are used to specify thefill
andstroke
properties, these colors will remain the same in high contrast mode, which could lead to insufficient contrast between the icon and the background or even make the icon invisible if its color matches the high contrast mode background.
Terms Used to Describe Trees
A tree item that can be expanded to reveal child items is called a parent node. It is a closed node when the children are hidden and an open node when it is expanded. An end node does not have any children. For a complete list of terms and definitions, see the Treeview Design Pattern.
Keyboard Support
Key | Function |
---|---|
Enter or Space |
|
Down arrow |
|
Up arrow |
|
Right Arrow |
|
Left Arrow |
|
Home | Moves focus to first node without opening or closing a node. |
End | Moves focus to the last node that can be focused without expanding any nodes that are closed. |
a-z, A-Z |
|
* (asterisk) |
|
Role, Property, State, and Tabindex Attributes
Landmarks
Role | Attribute | Element | Usage |
---|---|---|---|
banner |
header |
|
|
navigation |
nav |
Identifies the region containing the navigation tree. | |
aria-label="navigation label" |
nav |
The aria-label attribute provides an accessible name for the navigation landmark.
|
|
region |
section |
|
|
aria-labelledby="IDREFs" |
section |
The aria-labelledby attribute provides an accessible name for the region landmark by concatenating the website and page titles.
|
|
contentinfo |
role="contentinfo" |
footer |
|
Tree
Role | Attribute | Element | Usage |
---|---|---|---|
tree |
ul |
|
|
aria-label="Mythical University" |
ul |
Provides an accessible name for the tree . |
|
treeitem |
a |
Identifies the element as a treeitem . |
|
tabindex="-1" |
a |
|
|
tabindex="0" |
a |
|
|
aria-current="page" |
a |
|
|
aria-expanded="false" |
a |
|
|
aria-expanded="true" |
a |
|
|
aria-owns="IDREF" |
a |
Refers to the element with role group that contains the set of child treeitem elements that belong to this parent treeitem . |
|
group |
ul |
|
|
none
|
li
|
|
Javascript and CSS Source Code
- CSS: treeview-navigation.css
- Javascript: treeview-navigation.js
HTML Source Code
<!-- NOTE: In a real website the header element would be a top level element, i.e., it would have the body as its scope.
If the scope of the header element were body, browsers would automatically treat the header as an ARIA banner,
so the header would not need the role="banner". -->
<div class="page">
<header role="banner">
<div class="title" id="id_website_title">
Mythical University
</div>
<div class="tagline">
Using a Tree widget pattern for navigation links
</div>
</header>
<div class="body">
<nav aria-label="Mythical University">
<ul class="treeview-navigation"
role="tree"
aria-label="Mythical University">
<li role="none">
<a role="treeitem"
href="#home"
aria-current="page">
<span class="label">
Home
</span>
</a>
</li>
<li role="none">
<a role="treeitem"
aria-expanded="false"
aria-owns="id-about-subtree"
href="#about">
<span class="label">
<span class="icon">
<svg xmlns="http://www.w3.org/2000/svg"
width="13"
height="10"
viewBox="0 0 13 10">
<polygon points="2 1, 12 1, 7 9"></polygon>
</svg>
</span>
About
</span>
</a>
<ul id="id-about-subtree"
role="group"
aria-label="About">
<li role="none">
<a role="treeitem" href="#overview">
<span class="label">
Overview
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#adminstration">
<span class="label">
Administration
</span>
</a>
</li>
<li role="none">
<a role="treeitem"
aria-expanded="false"
aria-owns="id-facts-subtree"
href="#facts">
<span class="label">
<span class="icon">
<svg xmlns="http://www.w3.org/2000/svg"
width="13"
height="10"
viewBox="0 0 13 10">
<polygon points="2 1, 12 1, 7 9"></polygon>
</svg>
</span>
Facts
</span>
</a>
<ul id="id-facts-subtree"
role="group"
aria-label="Facts">
<li role="none">
<a role="treeitem" href="#history">
<span class="label">
History
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#current-statistics">
<span class="label">
Current Statistics
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#awards">
<span class="label">
Awards
</span>
</a>
</li>
</ul>
</li>
<li role="none">
<a role="treeitem"
aria-expanded="false"
aria-owns="id-campus-tours-subtree"
href="#campus-tours">
<span class="label">
<span class="icon">
<svg xmlns="http://www.w3.org/2000/svg"
width="13"
height="10"
viewBox="0 0 13 10">
<polygon points="2 1, 12 1, 7 9"></polygon>
</svg>
</span>
Campus Tours
</span>
</a>
<ul id="id-campus-tours-subtree"
role="group"
aria-label="Campus Tours">
<li role="none">
<a role="treeitem" href="#for-prospective-students">
<span class="label">
For Prospective Students
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#for-alumni">
<span class="label">
For Alumni
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#for-visitors">
<span class="label">
For Visitors
</span>
</a>
</li>
</ul>
</li>
</ul>
</li>
<li role="none">
<a role="treeitem"
aria-expanded="false"
aria-owns="id-admissions-subtree"
href="#admissions">
<span class="label">
<span class="icon">
<svg xmlns="http://www.w3.org/2000/svg"
width="13"
height="10"
viewBox="0 0 13 10">
<polygon points="2 1, 12 1, 7 9"></polygon>
</svg>
</span>
Admissions
</span>
</a>
<ul id="id-admissions-subtree"
role="group"
aria-label="Admissions">
<li role="none">
<a role="treeitem" href="#apply">
<span class="label">
Apply
</span>
</a>
</li>
<li role="none">
<a role="treeitem"
aria-expanded="false"
aria-owns="id-tuition-subtree"
href="#tuition">
<span class="label">
<span class="icon">
<svg xmlns="http://www.w3.org/2000/svg"
width="13"
height="10"
viewBox="0 0 13 10">
<polygon points="2 1, 12 1, 7 9"></polygon>
</svg>
</span>
Tuition
</span>
</a>
<ul id="id-tuition-subtree"
role="group"
aria-label="Tuition">
<li role="none">
<a role="treeitem" href="#undergraduate">
<span class="label">
Undergraduate
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#graduate">
<span class="label">
Graduate
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#professional-schools">
<span class="label">
Professional Schools
</span>
</a>
</li>
</ul>
</li>
<li role="none">
<a role="treeitem" href="#signup">
<span class="label">
Sign Up
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#visit">
<span class="label">
Visit
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#photo-tour">
<span class="label">
Photo Tour
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#connect">
<span class="label">
Connect
</span>
</a>
</li>
</ul>
</li>
<li role="none">
<a role="treeitem"
aria-expanded="false"
aria-owns="id-academics-subtree"
href="#academics">
<span class="label">
<span class="icon">
<svg xmlns="http://www.w3.org/2000/svg"
width="13"
height="10"
viewBox="0 0 13 10">
<polygon points="2 1, 12 1, 7 9"></polygon>
</svg>
</span>
Academics
</span>
</a>
<ul id="id-academics-subtree"
role="group"
aria-label="Academics">
<li role="none">
<a role="treeitem" href="#colleges-and-schools">
<span class="label">
Colleges & Schools
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#programs-of-study">
<span class="label">
Programs of Study
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#honors-programs">
<span class="label">
Honors Programs
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#online-courses">
<span class="label">
Online Courses
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#course-explorer">
<span class="label">
Course Explorer
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#register-for-classes">
<span class="label">
Register for Classes
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#academic-calendar">
<span class="label">
Academic Calendar
</span>
</a>
</li>
<li role="none">
<a role="treeitem" href="#tanscripts">
<span class="label">
Transcripts
</span>
</a>
</li>
</ul>
</li>
</ul>
</nav>
<!-- NOTE: In a real website the following SECTION element should be MAIN element -->
<section class="main" aria-labelledby="id_website_title id_page_title">
<h1 class="page_title" id="id_page_title">
Mythical University
</h1>
<div class="content">
<p></p>
</div>
</section>
</div>
<!-- NOTE: In a real website the footer element would be a top level element, i.e., it would have the body as its scope.
If the scope of the footer element were body, browsers would automatically treat the header as an ARIA contentinfo,
so the footer would not need the role="contentinfo". -->
<footer role="contentinfo">
Mythical University footer information
</footer>
</div>