Invalid ARIA role
aria/role-abstract
- WCAG success criterion
- 4.1.2 (level A)
- Outcome class
- Automatic. An automated check that can report a confirmed violation.
- Area
- Accessibility, Technical Robustness
- Default severity
- high
- axe-core rule
aria-roles
Why we flag this
Assistive technologies cannot determine the element's function.
Role value is not defined in the ARIA specification.
What the rule checks
Scope. role attributes on elements in the accessibility tree.
Expectation. Fails for every abstract role token (widget, landmark, command, section, ...): it has no mapping and conveys nothing. Concrete roles pass. Hidden subtrees are out of scope.
Source. WCAG 2.2 SC 4.1.2 Name, Role, Value; WAI-ARIA 1.2 section 5.3.1 ("Authors MUST NOT use abstract roles in content")
Detection: shared; needs dom, ax_tree.
Failing example
The check reports a violation here. Corpus case aria_roles_invalid, element div#filters. The page may contain further findings for other rules.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Order overview - Example shop</title>
</head>
<body>
<header>
<p>Example shop</p>
</header>
<main>
<h1>Order overview</h1>
<!-- aria/role-invalid: misspelled role, the element stays generic -->
<div id="orders" role="tabel">
<p>Order 1001 - shipped</p>
</div>
<!-- aria/role-abstract: abstract roles must not be authored -->
<div id="filters" role="widget" tabindex="0">Filter orders</div>
<!-- aria/role-redundant: the role repeats the implicit role -->
<button type="button" id="reorder" role="button">Reorder</button>
<!-- aria/required-parent-missing: tab outside any tablist -->
<div id="tab-returns" role="tab" tabindex="0" aria-selected="true">Returns</div>
<!-- aria/required-children-missing: a tablist owning buttons, not tabs -->
<div id="views" role="tablist" aria-label="Views">
<button type="button" id="view-list">List</button>
<button type="button" id="view-grid">Grid</button>
</div>
<!-- aria/required-attribute-missing: custom checkbox and switch without
aria-checked, combobox without aria-expanded -->
<div id="gift" role="checkbox" tabindex="0">Gift wrap</div>
<div id="express" role="switch" tabindex="0">Express delivery</div>
<div id="carrier" role="combobox" tabindex="0" aria-controls="carriers" aria-label="Carrier">Standard</div>
<ul id="carriers" role="listbox" aria-label="Carriers">
<li role="option" id="carrier-std" aria-selected="true">Standard</li>
<li role="option" id="carrier-fast">Fast</li>
</ul>
</main>
<footer>
<p>Example shop</p>
</footer>
</body>
</html>Passing example
The check passes here and reports nothing. Corpus case aria_roles_valid. The page may contain further findings for other rules.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Order overview - Example shop</title>
</head>
<body>
<header>
<p>Example shop</p>
</header>
<main>
<h1>Order overview</h1>
<!-- Valid concrete roles -->
<div id="orders" role="table" aria-label="Orders">
<div role="rowgroup">
<div role="row" id="order-head">
<span role="columnheader">Order</span>
<span role="columnheader">Status</span>
</div>
<div role="row" id="order-row">
<span role="cell">Order 1001</span>
<span role="cell">shipped</span>
</div>
</div>
</div>
<div id="filters" role="group" aria-label="Filter orders">
<button type="button" id="filter-open">Open orders</button>
</div>
<!-- A role that changes the element's semantics is not redundant -->
<a href="/orders/export" id="export" role="button">Export</a>
<!-- Tabs inside their tablist, through a generic wrapper; the tablist
owns a tab through aria-owns as well -->
<div id="views" role="tablist" aria-label="Views" aria-owns="view-map">
<div class="tab-wrap">
<div id="view-list" role="tab" tabindex="0" aria-selected="true" aria-controls="view-panel">List</div>
</div>
<div id="view-grid" role="tab" tabindex="-1" aria-selected="false" aria-controls="view-panel">Grid</div>
</div>
<div id="view-map" role="tab" tabindex="-1" aria-selected="false" aria-controls="view-panel">Map</div>
<div id="view-panel" role="tabpanel" aria-labelledby="view-list">Three orders.</div>
<!-- A busy feed may hold a placeholder instead of articles while loading -->
<div id="loading" role="feed" aria-busy="true" aria-label="Recent orders">
<p class="spinner">Loading</p>
</div>
<!-- Required states present; native controls carry them natively -->
<div id="gift" role="checkbox" tabindex="0" aria-checked="false">Gift wrap</div>
<div id="express" role="switch" tabindex="0" aria-checked="true">Express delivery</div>
<input type="checkbox" id="insure" role="switch">
<label for="insure">Insure parcel</label>
<div id="carrier" role="combobox" tabindex="0" aria-expanded="false" aria-controls="carriers" aria-label="Carrier">Standard</div>
<ul id="carriers" role="listbox" aria-label="Carriers" hidden>
<li role="option" id="carrier-std" aria-selected="true">Standard</li>
</ul>
<hr id="divider">
<div id="static-sep" role="separator"></div>
</main>
<footer>
<p>Example shop</p>
</footer>
</body>
</html>This page is generated from the rule catalogue and the rule contracts; see therule overview for how the outcome classes are derived.