ARIA attribute not allowed (aria-allowed-attr)

The aria-allowed-attr rule flags an ARIA attribute on an element whose role does not support it – aria-selected on a plain <button>, aria-checked on a link. Browsers do not pass such a state on, so the information you meant to give never arrives. The fix is either the right role for the widget, or the attribute that role does support.

What the rule means

WAI-ARIA 1.2 defines, for every role, which states and properties it supports [3]. Global attributes such as aria-label, aria-describedby or aria-hidden work almost everywhere. Widget states do not: aria-selected belongs to tab, option, row, gridcell and a few more; aria-checked to checkbox, radio, switch and the checkable menu items; aria-pressed to button. The role that counts is the element's actual role – written in role, or the one HTML gives it: <button> is a button, <a href> is a link, <li> is a list item.

axe fails every attribute that is not in the role's list. It asks a person instead when the attribute is deprecated in ARIA 1.2, such as aria-grabbed or aria-dropeffect, and when it cannot be sure of the role of an unknown custom element.

Two related problems belong to other axe rules: a misspelled attribute name (aria-labeledby) and a name on an element that must not be named, such as aria-label on a plain <div>. aria-allowed-attr passes both.

Who is affected

Screen reader users are told the role and nothing more: "Reviews, button" instead of "Reviews, tab, selected, 2 of 3". They cannot tell which tab is active or which page of the navigation they are on. Voice control users may not be able to address the control by what it looks like. Everybody who relies on the accessibility tree gets less than the sighted mouse user sees.

Why the check fails

  • Tabs made of plain buttons, with aria-selected on each button but no role="tab" or role="tablist".
  • Navigation marking the current page with aria-selected="true" on a link instead of aria-current="page".
  • Toggle buttons using aria-checked where a button supports aria-pressed.
  • Accordion or menu items with aria-expanded on a <li> rather than on the button inside it.
  • A role removed or changed in a refactor while the attributes stayed.
  • Copied snippets from an older ARIA version, with deprecated attributes like aria-grabbed.

How to fix it

  1. Decide what the widget is: a set of tabs, a toggle, a navigation. Look up the pattern in the ARIA Authoring Practices Guide [5].
  2. Give each element the role that pattern names, so the attribute becomes valid.
  3. Or keep the element as it is and swap the attribute for one its role supports – aria-pressed on a button, aria-current on a link.
<!-- Before: plain buttons carrying a state only tabs support -->
<div class="tabs">
  <button class="tabs__tab is-active" aria-selected="true">Specifications</button>
  <button class="tabs__tab" aria-selected="false">Reviews</button>
</div>
<div class="tabs__panel" id="panel-specs"><p>Weight: 1.2 kg</p></div>
<!-- After: tab roles, so aria-selected is supported and announced -->
<div class="tabs" role="tablist" aria-label="Product details">
  <button class="tabs__tab" role="tab" id="tab-specs" aria-selected="true"
          aria-controls="panel-specs">Specifications</button>
  <button class="tabs__tab" role="tab" id="tab-reviews" aria-selected="false"
          aria-controls="panel-reviews" tabindex="-1">Reviews</button>
</div>
<div class="tabs__panel" role="tabpanel" id="panel-specs" aria-labelledby="tab-specs"><p>Weight: 1.2 kg</p></div>
<div class="tabs__panel" role="tabpanel" id="panel-reviews" aria-labelledby="tab-reviews" hidden><p>4.6 of 5</p></div>

The current page in a navigation needs no new role, only the attribute a link supports:

<!-- Before: links cannot be "selected" -->
<nav aria-label="Main"><a href="/shop/" aria-selected="true">Shop</a> <a href="/about/">About</a></nav>
<!-- After: aria-current is allowed on every element -->
<nav aria-label="Main"><a href="/shop/" aria-current="page">Shop</a> <a href="/about/">About</a></nav>

A role brings keyboard behaviour with it: tabs move with the arrow keys. Adding role="tab" without that behaviour fixes the rule and leaves the widget half built.

How to test it manually

  1. Select the element in your browser's developer tools and open the Accessibility pane: an unsupported attribute is not listed among the element's states.
  2. With a screen reader such as NVDA (free) or VoiceOver, move to the tabs or the navigation and listen for "selected" or "current page".
  3. For a widget that got a new role, check its keyboard pattern too – arrow keys for tabs, Space or Enter for toggles.
  4. What the rule cannot see: whether the role you chose is the right one for the widget.

4.1.2 Name, Role, Value, Level A: roles and states must be exposed correctly. A tab set that is not announced as one also loses structure covered by 1.3.1 Info and Relationships.

How Reviseberg reports it

Reviseberg runs aria-allowed-attr on every crawled page. The issue list shows the rule with its severity, WCAG 4.1.2 and Level A, the number of elements and pages, and the points a fix gets you back; the detail view shows the selector, the HTML snippet with the attribute and every affected page. Deprecated attributes and unclear roles go to the Potential issues queue for a person to decide; they cost nothing and are never counted as a pass. Findings can be marked "ignore", "can't fix" or "false positive" with a reason, and every decision is logged.

  • undefined – the attribute is allowed, but its value is not.
  • undefined – a state the role needs is missing.
  • undefined – a tab outside a tablist, or an option outside a listbox.

Check your site for unsupported ARIA – get a free scan

Frequently asked questions

Is aria-label allowed on a <div>?

aria-allowed-attr does not object, because aria-label is a global attribute. But a <div> without a role must not be named, and browsers often ignore the label. Give it a role, or put the text somewhere visible.

Why is aria-current fine where aria-selected is not?

aria-current is global and meant for exactly this: the current page, step or date in a set. aria-selected is a widget state for things like tabs and options.

Can I just remove the attribute?

If it carried nothing the role can express, yes. If it carried real information – which tab is open – give the element the right role instead, or that information disappears.

Does the rule check my custom elements?

Yes, when they have a role. Without one, axe cannot know which attributes are allowed and asks a person.

Sources

  1. W3C, Understanding SC 4.1.2 Name, Role, Value – https://www.w3.org/WAI/WCAG22/Understanding/name-role-value
  2. Deque University, axe-core 4.13 rule aria-allowed-attr – https://dequeuniversity.com/rules/axe/4.13/aria-allowed-attr
  3. W3C, Accessible Rich Internet Applications (WAI-ARIA) 1.2 – https://www.w3.org/TR/wai-aria-1.2/
  4. W3C, ACT rule: ARIA state or property is permitted – https://www.w3.org/WAI/standards-guidelines/act/rules/5c01ea/
  5. W3C, ARIA Authoring Practices Guide: Tabs pattern – https://www.w3.org/WAI/ARIA/apg/patterns/tabs/

See what a scan finds on your site

One page in about thirty seconds, no email needed. The full report covers up to 100 pages and a keyboard journey.