# Accessibility Tree

> Canonical HTML version: https://rocketvalidator.com/glossary/accessibility-tree
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

The accessibility tree is a parallel structure to the DOM tree that browsers construct to represent the semantic meaning of a web page for assistive technologies such as screen readers, braille displays, and voice control software.

Every time a browser renders a web page, it builds the Document Object Model (DOM) from the HTML source. Alongside the DOM, the browser also constructs another tree-like structure called the accessibility tree. This tree strips away purely visual or decorative information and retains only the semantically meaningful content—roles, names, states, properties, and relationships—that assistive technologies need to communicate the page to users with disabilities. In essence, the accessibility tree is what a screen reader "sees" when it reads a page.

The accessibility tree is not a separate specification you implement directly; it is an internal browser construct derived from the combination of semantic HTML elements, ARIA attributes, and CSS properties. Each node in the accessibility tree is called an "accessible object" and carries properties such as an accessible name (computed through the accessible name computation algorithm), a role (like `button`, `link`, or `heading`), a state (like `disabled`, `expanded`, or `checked`), and a value where applicable.

## Why the accessibility tree matters

The accessibility tree is the critical bridge between your code and the experience of users who rely on assistive technologies. If the tree is incomplete, inaccurate, or poorly structured, those users may encounter pages that are confusing, unusable, or completely opaque.

Screen readers do not parse raw HTML. They query the browser's accessibility APIs—such as MSAA/UIA on Windows, ATK/AT-SPI on Linux, and the Accessibility API on macOS—which in turn read from the accessibility tree. When an element lacks a proper role or accessible name, it either disappears from the tree entirely or appears as a generic, unlabeled object. This directly violates WCAG success criteria like 1.3.1 (Info and Relationships), 4.1.2 (Name, Role, Value), and 2.4.6 (Headings and Labels).

Beyond screen readers, the accessibility tree affects voice control software (users who say "click Submit" need a button named "Submit" in the tree), switch devices, and braille displays. Getting the accessibility tree right means getting the experience right for a wide range of users.

## How the accessibility tree works

### Building the tree from the DOM

The browser walks the DOM and decides, for each element, whether and how it should appear in the accessibility tree. Native HTML elements carry implicit roles: an `<a>` with an `href` becomes a `link`, a `<button>` becomes a `button`, a `<table>` becomes a `table`, and so on. This is why semantic HTML is the foundation of a good accessibility tree—using the correct element gives you the correct role for free.

### ARIA's role in shaping the tree

When native HTML semantics are insufficient or when custom widgets are built with generic elements like `<div>` or `<span>`, WAI-ARIA attributes let you explicitly define roles, states, and properties. Adding `role="tab"` to a `<div>` inserts it into the tree as a tab. Adding `aria-expanded="false"` communicates its state. Adding `aria-label` or `aria-labelledby` provides its accessible name.

However, ARIA does not change behavior—it only changes how the element is represented in the accessibility tree. A `<div role="button">` will appear as a button in the tree but will not be keyboard-focusable or respond to Enter/Space keypresses unless you add that functionality yourself.

### Elements excluded from the tree

Not everything in the DOM appears in the accessibility tree. Elements hidden with `display: none` or `visibility: hidden`, as well as elements carrying `aria-hidden="true"`, are pruned from the tree. Purely presentational elements marked with `role="presentation"` or `role="none"` also lose their semantic meaning in the tree.

### Inspecting the accessibility tree

Modern browser DevTools let you inspect the accessibility tree directly. In Chrome, the Accessibility pane in the Elements panel shows each node's computed role, name, and properties. Firefox offers a dedicated Accessibility Inspector. These tools are invaluable for verifying that your markup produces the tree you intend.

## Code examples

### Bad example: generic elements with no semantic meaning

```html
<div class="nav">
  <div class="nav-item" onclick="goHome()">Home</div>
  <div class="nav-item" onclick="goAbout()">About</div>
</div>
```

In the accessibility tree, these `<div>` elements appear as generic containers with no role, no keyboard focus, and no indication that they are interactive. A screen reader user will not know they are navigation links.

### Good example: semantic HTML producing a rich accessibility tree

```html
<nav aria-label="Main navigation">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
  </ul>
</nav>
```

Here, `<nav>` maps to the `navigation` landmark role with the accessible name "Main navigation." Each `<a>` maps to the `link` role, is keyboard-focusable by default, and derives its accessible name from its text content. The accessibility tree is clear and complete.

### Bad example: custom widget missing ARIA attributes

```html
<div class="accordion-header" onclick="toggle()">
  FAQ Section
</div>
<div class="accordion-panel">
  <p>Here are the answers to common questions.</p>
</div>
```

The accessibility tree shows a generic text node with no indication it is expandable or interactive.

### Good example: custom widget with proper ARIA

```html
<h3>
  <button aria-expanded="false" aria-controls="faq-panel">
    FAQ Section
  </button>
</h3>
<div id="faq-panel" role="region" aria-labelledby="faq-heading" hidden>
  <p>Here are the answers to common questions.</p>
</div>
```

Now the accessibility tree contains a `button` with the accessible name "FAQ Section," an `aria-expanded` state of `false`, and a clear relationship to the panel it controls. When the panel is shown, updating `aria-expanded="true"` and removing the `hidden` attribute keeps the tree in sync with the visual state.

The accessibility tree is ultimately where all your semantic HTML and ARIA work converges. Writing valid, semantic markup and verifying the resulting tree with browser DevTools is one of the most effective ways to ensure your site works for everyone.
