ARIA Rule

ARIA attributes must be allowed for the element's role aria-allowed-attr

Every ARIA role comes with a short list of attributes it understands. aria-checked belongs on a checkbox, aria-pressed on a toggle button, aria-valuenow on a slider. Put an attribute on a role that does not support it and the browser either drops it or passes on something that makes no sense, so the control looks right on screen but is announced wrong.

Websight reports this as Elements must only use supported ARIA attributes

Who it affects

Someone using a screen reader hears a state that does not fit the control, like expanded on a checkbox, or misses the one state that mattered because it was written with the wrong attribute.

Someone using a braille display reads a short state code next to the control that is wrong or missing, and has no voice to double-check it against.

A developer three months from now sees an attribute that looks deliberate, trusts it, and copies the bug into the next component.

Broken versus fixed

Both examples are live and rendered in a sandboxed frame. The broken one is deliberately broken.

Broken

It is plainly ticked on screen. A screen reader announces: Email me when my order ships, checkbox, not checked. aria-selected means nothing on a checkbox, so the tick is invisible.

Fixed

Announced: Email me when my order ships, checkbox, checked. Same pixels, right attribute. (The demo is static markup, so clicking it will not toggle anything.)

Show the markup behind both examples
Broken
<style>body{font-family:system-ui;padding:16px;margin:0}.box{display:inline-flex;align-items:center;gap:10px}.sq{width:20px;height:20px;border:2px solid #2b6cb0;border-radius:4px;background:#2b6cb0;position:relative}.sq::after{content:"";position:absolute;left:6px;top:2px;width:5px;height:10px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg)}</style>
<div class="box" role="checkbox" aria-selected="true" tabindex="0">
  <span class="sq"></span>
  Email me when my order ships
</div>
Fixed
<style>body{font-family:system-ui;padding:16px;margin:0}.box{display:inline-flex;align-items:center;gap:10px}.sq{width:20px;height:20px;border:2px solid #2b6cb0;border-radius:4px;background:#2b6cb0;position:relative}.sq::after{content:"";position:absolute;left:6px;top:2px;width:5px;height:10px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg)}</style>
<div class="box" role="checkbox" aria-checked="true" tabindex="0">
  <span class="sq"></span>
  Email me when my order ships
</div>

Test it by hand in two minutes

  1. Right click the control, choose Inspect, and read every attribute that starts with aria- on the element with the role attribute.
  2. In Chrome DevTools open the Accessibility pane (under the Elements tab). Attributes the browser does not understand for that role are missing from the computed properties list.
  3. Turn on VoiceOver (Cmd+F5 on a Mac) or NVDA on Windows and Tab to the control. Check the state you hear matches what you see: ticked, pressed, expanded, selected.
  4. Change the control (tick it, open it) and listen again. If the announcement never changes, the state is being written to an attribute the role ignores.

The fix

Before
<div role="checkbox" aria-selected="true" tabindex="0">Email me when my order ships</div>
After
<div role="checkbox" aria-checked="true" tabindex="0">Email me when my order ships</div>

Find the attribute the role actually uses for that state and move the value across. If there is no such attribute, the role is probably the wrong one for what you are building.

Toggle button written with aria-checked

Before
<button aria-checked="true">Bold</button>
After
<button aria-pressed="true">Bold</button>

A button does not understand aria-checked. aria-pressed is the attribute for a button that stays on or off.

Selection state on the listbox instead of the option

Before
<ul role="listbox" aria-selected="true">
  <li role="option">Standard delivery</li>
</ul>
After
<ul role="listbox">
  <li role="option" aria-selected="true">Standard delivery</li>
</ul>

aria-selected belongs on the thing that is selected, the option, not on the container.

Common mistakes

  • Adding a second attribute alongside the wrong one and leaving both, so two states can disagree.
  • Changing the role to one that happens to allow the attribute, which breaks the announcement in a different way.
  • Guessing attribute names from what sounds right (aria-selected for a tick, aria-open for a menu) instead of checking the role.
  • Removing the attribute without replacing it, so the state is gone from the announcement entirely.
  • Using a native input with a checked attribute and then also writing aria-checked, which can fall out of step.

WCAG criteria this rule maps to

axe-core tags this rule as WCAG 2.2 level A. It is one of the checks for:

The scanner reads the role and compares every aria- attribute against the list that role supports, so this one is caught reliably. It cannot tell which attribute you meant, so it may also raise aria-required-attr on the same element until the right one is in place. Automated tools find only part of the accessibility problems on a page; a pass on this rule is not a pass on the criterion.

Scan your own page for this and 63 other checks

Open any page in Chrome, click Websight, and get a score out of 100 with every issue explained and a draft fix snippet per element.

Add Websight to Chrome

Free scans, no account, nothing leaves your computer. Automated tools find only part of the problems; the extension says so on every report.