Skip to main content
WCAGrules
Quick navigation

ARIA property

aria-level

The depth of a heading or a tree item, counting from one.

It sets the depth, so an element with a heading role and a level of 3 lands where an h3 would in the outline. Change it and the outline changes. The visual size does not move with it, so the two can disagree without anything looking wrong.

Which roles may carry aria-level

Value
integer
Filed as
A property, which is how ARIA files it and not a rule about how often it changes.
Roles that may carry it
heading, listitem, row
Roles that inherit it
treeitem

Those lists are not advice. Browsers are required to ignore a non-global attribute sitting on a role that does not support it, so aria-level on the wrong element is not weak, it is absent. You can read it in the DOM and nobody using a screen reader can.

Every role above comes from the specification's own list for this attribute, checked name for name. The normative definition stays with the W3C, in the aria-level section of the ARIA specification.

Keeping aria-level true

Leave it off a heading and the outline still gets a number, because the fallback is level 2. That is the sharpest example of the failure these pages are about. Forget the attribute and you do not get silence, you get a confident wrong answer that files every unlevelled heading at the same depth. Two placement rules go with it. It goes on the leaf rather than the container, so a tree item carries it and the group around it does not, which the spec explains as keeping one way for assistive technology to read it. On a treegrid it goes on the row rather than the cell. And when the tree gets restructured, the levels have to be recomputed along with it.

How aria-level gets checked

There are test rules that check an ARIA attribute is one that exists, is allowed on the role underneath it, and carries a value of the right type. What they map to is ARIA's own author requirements rather than any WCAG criterion, so a misplaced attribute breaks ARIA without being a WCAG failure by itself. It becomes one under 4.1.2 Name, Role, Value the moment the missing or wrong value means the control's state cannot be worked out programmatically, which is what usually happens next.

Nothing automated catches the failure this page is about. A stale value is a valid value, on a permitted role, with the right type. It is only wrong about the world.

Attributes you will meet alongside aria-level

  • aria-colindex Which column a cell is in, counting from the real table rather than what is shown.
  • aria-expanded Whether the thing this control opens is currently open.
  • aria-posinset Which position this item holds in its set, when the markup does not contain the whole set.
  • aria-rowindex Which row this is, counting from the real table.
  • aria-selected Whether an option, tab or row is the chosen one.
  • aria-setsize How many items the set really holds, when only some are in the markup. Together with aria-posinset this is what makes an infinite list announce as 5 of 200.

Every ARIA state and property · Every ARIA role · ARIA explained

Go somewhere useful

Find tools, resources and your workspace.

29 destinations