Use role=heading when h1-h6 is impossible
role=heading marks an element as a heading, and W3C says it must be paired with aria-level to say which level. W3C lists it as sufficient for 1.3.1 Info and Relationships. It is a last resort, and W3C's reason is more concrete than the usual advice. ARIA changes only what software is told, so a div carrying role=heading is not treated as a heading by anything that reads the element itself, which includes a browser's reader mode. A real h2 gets restyled there. The div does not. The one case that genuinely needs this technique is a document deep enough to want a level beyond h6, since HTML stops at six and aria-level does not. Everywhere else, change the div.
How we find it in an audit
The role and the level are both automated finds, including a role=heading with no aria-level on it. The judgment is the same one heading work always needs. Whether the level matches the outline the page actually has, and whether the thing was ever a heading rather than a bolded first line somebody liked the look of.
How affected users experience it
Heading navigation is the most-used way around a long page, and a styled div is not in that list. A screen-reader user pressing H past a panel titled Delivery options skips straight over it, so the section exists on screen and does not exist in the map. Adding the role puts it back in the list. Using a real h2 puts it back in the list and in reader mode and in every other tool that reads the markup.
Passes vs. fails
Passes
<div role="heading" aria-level="2">Delivery options</div>
<!-- better still, when the markup allows it: <h2>Delivery options</h2> -->Fails
<div class="panel-title">Delivery options</div>How this gets tested
The W3C publishes test rules that define what a checker looks for here.
- ARIA attribute is defined in WAI-ARIAA tool can check this
- ARIA state or property has valid valueA tool can check this
- Element with role attribute has required states and propertiesA tool can check this
- Form field has non-empty accessible nameA tool can check this
- Headers attribute specified on a cell refers to cells in the same table elementA tool can check this
- Role attribute has valid valueA tool can check this
- ARIA global properties not used where prohibitedA tool can check this
- ARIA required context roleA tool can check this
- ARIA required owned elementsA tool can check this
- ARIA state or property is permittedA tool can check this
- Table header cell has assigned cellsA tool can check this
Other ways to satisfy this rule
52 guides on this site are filed under 1.3.1 Info and Relationships. W3C lists this one as sufficient for that rule on its own. Implement it correctly, in a way your readers' software actually supports, and the rule is met.
- ARIA11sufficientAdd landmarks so users can skip around
- ARIA13sufficientName repeated landmarks so they are distinguishable
- ARIA16sufficientName controls from visible text with aria-labelledby
- ARIA17sufficientGroup related form fields with ARIA roles
- ARIA20sufficientMark leftover page areas with role=region
- ARIA24sufficientGive meaningful font icons role=img
This guide is our interpretation of W3C technique ARIA12: Using role=heading to identify headings. W3C publishes its techniques as guidance rather than as the standard, and says so on every one of them. The success criterion is what conformance is measured against, and a technique is one documented way to meet it.