How to fix an ARIA role that isn't allowed on its element?
aria-allowed-role page
The issue
A screen reader announces an element as one thing while it behaves as another. A <ul> given role="button" is read as a button but has none of a button’s keyboard behavior. A link given role="heading" is read as a heading, and nothing tells the user it goes anywhere. The user is told what to expect and then gets something else.
The cause is a role attribute that overrides the element’s own meaning with one HTML doesn’t permit for it. Each element has a set of roles it may take; some, like <div> and <span>, accept any, and some, like <html> or <script>, accept none. This rule is a best practice rather than a WCAG criterion, but it usually points at markup that will fail one.
Scope
Every visible element with a valid role value is checked against the roles allowed on its tag. <col>, <colgroup>, <head>, <html>, <meta>, <script> and <style> fail with any role. Elements probeo has no restriction for pass. An invalid role value is left to the ARIA attribute checks.
How to check you have it
- In probeo: the page reports
aria-allowed-role, “ARIA role should be appropriate for the element”, with minor impact, naming the role and the element it isn’t allowed on. - By hand: search the page source for
role="and compare each role with its element in the ARIA in HTML tables, which list the roles each element may take. - With a tool: axe DevTools reports the same rule id.
The fix
Use the element that already has the role you want, or remove the role.
A clickable control should be a <button>, not a list or a heading with role="button". If the role only repeats the element’s own meaning, such as role="list" on a <ul>, delete it. If you need a role on an element that doesn’t allow it, wrap the content in a <div> or <span> and put the role there.
<!-- Before -->
<h3 role="button" onclick="toggle()">Shipping</h3>
<!-- After -->
<h3><button type="button" aria-expanded="false">Shipping</button></h3>Done when: every role attribute is one its element allows, and the check above comes back clean.
Do not
- Do not add a role to give an element behavior; a role changes only what is announced.
- Do not put roles on
<html>,<head>,<meta>,<script>or<style>. - Do not give a link or button a role that hides what it does, such as
headingorlistitem.
FAQ
Is a minor impact worth fixing?
Usually. The rule rarely blocks anyone on its own, but the role is often a sign that the element’s keyboard behavior is missing too. Fixing the element tends to fix both.
Why is role="presentation" on a <ul> allowed?
Lists may take none or presentation, which strips the list semantics while keeping the content. It is a legitimate choice for a list used purely for layout, such as a row of icons.
What if a framework adds the role?
Check the component’s options first; many accept a different element or tag name. If not, wrap the content in an element that allows the role rather than leaving the mismatch in place.
Which product detects this
Probeo checks this on every page of your site as part of Site Clarity. This page explains one instance; the product tells you every page that has it.