tree
Marks an element as a hierarchical container of treeitems — a file explorer, nested categories, or org chart. Single-tab-stop, arrow-key navigation, expand/collapse. There is no native HTML equivalent.
When to use
For a true hierarchical browser: file system, organisation chart, deeply nested taxonomy. Children are role="treeitem", grouped as needed by intermediate role="group" wrappers.
If your “tree” is really a navigation menu of two-or-three-level links, do not use role="tree". Use <nav> with nested <ul> and <a> instead — Tab + Enter is what users expect for navigation; arrow-key tree navigation in a site menu is unfamiliar and slow.
A tree MUST have an accessible name. Set aria-multiselectable="true" if multiple treeitems can be selected at once.
Keyboard + focus contract
Per the APG treeview pattern:
- Tab moves into the tree, onto the focused (or first) treeitem; Tab moves OUT.
- Up/Down arrows move focus between visible nodes, skipping collapsed children.
- Right arrow: if collapsed, expand; if expanded, move to first child.
- Left arrow: if expanded, collapse; if collapsed, move to parent.
- Home / End move to first / last visible node.
- Enter or Space selects the current treeitem.
- Typeahead: typing letters jumps to matching visible nodes.
- For multi-select trees: Shift+Arrow extends contiguous selection; Ctrl/Cmd+Click toggles individual selection.
Use a roving tabindex: only the currently focused treeitem has tabindex="0".
Common failures
- Every treeitem with
tabindex="0". The pattern is single-tab-stop. - Tree with no accessible name. Screen-reader landmark navigation has nothing to announce.
- Child treeitems inside parent without a wrapping
role="group". Screen readers cannot announce the group as a unit. aria-expanded="false"on leaf treeitems — announces an empty collapsible state.- Right/Left arrows used for next/previous sibling instead of expand/collapse.
Example
<ul role="tree" aria-label="Project files">
<li role="treeitem" aria-expanded="true" tabindex="0">
src
<ul role="group">
<li role="treeitem" tabindex="-1">index.ts</li>
<li role="treeitem" aria-expanded="false" tabindex="-1">
components
<ul role="group">
<li role="treeitem" tabindex="-1">Button.tsx</li>
</ul>
</li>
</ul>
</li>
<li role="treeitem" tabindex="-1">README.md</li>
</ul>