Standards · ARIA

Role Composite widget

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>