Standards · ARIA

Property Widget state

aria-level

Indicates the hierarchical level of an element within a structure. Required on role="heading" elements; also used on role="treeitem" and role="listitem" inside nested lists. Integer value, starting at 1.

When to use

On role="heading" to declare the heading’s depth — the ARIA equivalent of choosing <h1><h6>. The native heading elements should be your default; reach for role="heading" + aria-level only when you need a level higher than 6, or when you’re constrained by a framework that won’t let you use a heading element directly.

Also valid on role="treeitem" (depth in the tree, starting at 1 for top-level items) and on role="listitem" inside a nested role="list" when the nesting isn’t expressed by the DOM structure.

How it behaves

The value is a positive integer. For headings, 1–6 maps to <h1><h6>; values above 6 are valid in ARIA but only a few screen readers expose them, so don’t depend on level 7 being announced as such.

For tree items, the level is the depth: the root of a tree is level 1, its direct children are level 2, and so on. The level number lets a screen-reader user understand where they are in the hierarchy without seeing the indentation.

The attribute does not change visual styling. If your “ARIA heading level 4” needs to look like an h4, you style it yourself.

Common failures

  • Using role="heading" plus aria-level="3" instead of just <h3>. The native element gives you the role, the level, default keyboard navigation, and document-outline integration for free.
  • Setting aria-level on an element without role="heading", role="treeitem", or role="listitem". The attribute has no effect on, for instance, a <button> or a <div> with no role.
  • Skipping a level — a level 2 followed by a level 4 confuses the document outline and trips SC 1.3.1 audits.
  • Treeitems with the wrong level: every child of a level-2 item must be level 3. Off-by-one errors here break the “moved up a level” / “moved down a level” announcements.
  • Non-integer or zero values. Only positive integers are valid; aria-level="0" is ignored.
  • Forgetting to update aria-level when items are reparented in a draggable tree.

Example

<!-- Heading deeper than h6 (rare; needed in complex outlines) -->
<div role="heading" aria-level="7">Sub-sub-sub-section</div>

<!-- Treeitems express depth via aria-level -->
<ul role="tree">
  <li role="treeitem" aria-level="1" aria-expanded="true">
    Documents
    <ul>
      <li role="treeitem" aria-level="2">Invoices</li>
      <li role="treeitem" aria-level="2">Contracts</li>
    </ul>
  </li>
</ul>