What Are ARIA Allowed Attributes? Complete Guide (2026)
What Are ARIA Allowed Attributes?
ARIA attributes have strict rules about which roles they may appear on. The aria-allowed-attr audit catches ARIA states or properties used on roles that do not support them — for example, aria-checked on role="button". The WAI-ARIA specification only permits aria-checked on checkbox, menuitemcheckbox, menuitemradio, radio, switch, option, and treeitem. Misused ARIA is worse than no ARIA — it actively confuses assistive technology.
Key Facts (TL;DR)
- WCAG criterion: WCAG 2.2 Success Criterion 4.1.2 Name, Role, Value (Level A). Invalid ARIA makes role/state unreliable for assistive tech.
- Three related audits:
aria-allowed-attr(attribute disallowed on role),aria-valid-attr(attribute name not in spec / typo),aria-valid-attr-value(valid attribute, invalid value token). - First Rule of ARIA (W3C): If a native HTML element exists, use it instead of recreating the behavior with
role+ ARIA. - Why it's common: WebAIM's 2025 Million homepage analysis again found that pages using ARIA averaged more detected accessibility errors than pages without it — almost entirely because of misuse.
- How to spot it: Browsers silently ignore unknown ARIA attributes, so the bug is invisible until tested with a screen reader or an automated checker.
Think of ARIA the way you think of legal grammar: aria-checked="mixed" is a real sentence, but only when the subject is a checkbox. Put the same word next to a button and the sentence stops parsing.
Why ARIA Allowed Attributes Matter
ARIA is the layer that tells assistive technology what each control IS, what STATE it's in, and what RELATIONSHIPS it has. When that layer disagrees with the role of the element, screen readers either ignore the attribute or — worse — announce a state that doesn't match what the user sees.
- Screen-reader regressions: A
<button>witharia-checked="true"may be announced as either "button" or "checked" depending on the screen reader. Users get inconsistent behavior across NVDA, JAWS, VoiceOver, and TalkBack. - Silent failure on typos:
aria-lableandaria-pressed-stateare not in the spec. Browsers do not warn — the attribute is simply dropped. The visible UI looks fine; the screen-reader experience is broken. - WCAG 4.1.2 violations: Name, Role, Value is a Level A criterion. ARIA misuse is one of the most-cited ways to fail it.
- Legal exposure: US ADA and EU EAA (European Accessibility Act, in force June 2025) lawsuits routinely cite invalid ARIA in technical evidence.
- AI search visibility: AI answer engines lean on semantic HTML and ARIA to understand structure. Pages with broken ARIA produce noisier accessibility trees and weaker structured signals.
The Three Audits That Catch Bad ARIA
Most automated checkers (axe-core, the open-source rules engine behind many tools, plus the rules baked into Chrome DevTools' Issues panel) split ARIA validation into three separate checks. Knowing which one fired tells you what to fix.
1. aria-allowed-attr — wrong attribute on this role
The attribute name is real, but the role of the element does not support it. Example: aria-checked on role="button". The fix is either to change the role to one that allows the attribute (often switch or checkbox), or to drop the attribute and use the right native element.
2. aria-valid-attr — attribute name not in the spec
The attribute itself does not exist. Usually a typo (aria-lable, aria-decribedby) or a made-up name (aria-pressed-state). Browsers ignore unknown ARIA attributes silently.
3. aria-valid-attr-value — invalid value token
The attribute is real and allowed on this role, but the value is not one of the spec-permitted tokens. aria-pressed="yes" fails — the only valid values are "true", "false", and "mixed". aria-expanded="open" fails — must be "true" or "false".
How to Check Your Pages
- Greadme deep scan — runs the full ARIA validity rule set, lists every offending element with the role, attribute, and reason, and offers a one-click GitHub PR fix where applicable.
- Greadme crawler scan — checks ARIA validity across every indexable page so you can find templates (modals, tab strips, custom selects) that repeat the same mistake site-wide.
- Greadme AI visibility analyzer — surfaces how clean accessibility markup affects how AI answer engines understand and cite your pages.
- Chrome DevTools → Issues panel — flags many invalid ARIA attributes inline as you load a page, with a link to the offending element.
- axe-core (the open-source rules engine) — integrates into Jest, Playwright, Cypress, and Storybook for build-time validation.
- Manual screen-reader test — load the page in NVDA (Windows), VoiceOver (macOS/iOS), or TalkBack (Android) and tab through. If a control is announced wrong, the ARIA is wrong.
Bad vs Good: Real Examples
Three of the most common ARIA validity failures, side by side:
<!-- BAD: aria-checked is not allowed on role="button" -->
<button aria-checked="true">Subscribe</button>
<!-- BAD: aria-lable is a typo; browsers silently drop it -->
<button aria-lable="Close dialog">×</button>
<!-- BAD: "yes" is not a valid value for aria-pressed -->
<button aria-pressed="yes">Bold</button>
<!-- GOOD: use role="switch" (or <input type="checkbox">) -->
<button role="switch" aria-checked="true">Subscribe</button>
<!-- GOOD: correct attribute name -->
<button aria-label="Close dialog">×</button>
<!-- GOOD: tokens must be true | false | mixed -->
<button aria-pressed="true">Bold</button>In every case, the simplest fix is a more honest description of what the element actually is. If it's a toggle, mark it as a switchor use a checkbox. If it's a button, drop the state attributes that don't apply.
10 Rules to Avoid ARIA Validity Errors
1. Prefer Native HTML Over role="..."
<button>, <input type="checkbox">, <dialog>, and <details> handle role, state, focus, and keyboard for free. Recreating them with div + ARIA is where most validity bugs are born.
2. Match the Attribute to the Role's Allowed List
Before adding an ARIA attribute, check the role's entry in the WAI-ARIA spec on MDN. Every role lists exactly which states and properties are supported.
role="button" -> aria-pressed, aria-expanded, aria-disabled (no aria-checked)
role="checkbox" -> aria-checked, aria-required, aria-readonly
role="switch" -> aria-checked
role="tab" -> aria-selected, aria-controls
role="slider" -> aria-valuenow, aria-valuemin, aria-valuemax, aria-valuetext3. Use Only Spec-Permitted Value Tokens
ARIA boolean attributes accept "true" / "false" (sometimes "mixed"). Not "yes", not "1", not "on". aria-live accepts "off" / "polite" / "assertive". aria-level accepts an integer 1–9.
4. Don't Put Widget States on Static Elements
aria-expanded on a plain <div> with no interactive role is meaningless. State attributes belong on focusable controls with the matching widget role.
5. Verify ID References Exist
aria-labelledby, aria-describedby, aria-controls, and aria-owns all reference IDs. A reference to a missing ID is silently dropped.
6. Don't Duplicate Native Semantics
<button disabled aria-disabled="true"> is redundant — disabled already does this. <nav role="navigation"> repeats what <nav> says. Pick one.
7. Update States When the UI Changes
aria-expanded set to "false" at render and never updated is a common bug. Toggle it whenever the visual state toggles.
function Disclosure({ children, label }) {
const [open, setOpen] = useState(false);
const id = useId();
return (
<>
<button aria-expanded={open} aria-controls={id} onClick={() => setOpen(o => !o)}>
{label}
</button>
<div id={id} hidden={!open}>{children}</div>
</>
);
}8. Don't Use Abstract Roles
Roles like widget, roletype, command, and composite are abstract — they exist to describe the role taxonomy and must never be used on real elements.
9. Lint at Build Time
The eslint-plugin-jsx-a11y rules aria-props, aria-proptypes, aria-unsupported-elements, role-supports-aria-props, and role-has-required-aria-props catch the entire family of validity errors before merge.
10. Don't Hide Focusable Elements
aria-hidden="true" on a focusable element is a special class of validity error: the element stays in the tab order but is invisible to assistive tech. Either remove it from the tab order with tabindex="-1", or remove aria-hidden.
Common ARIA Validity Issues and Fixes
Problem: aria-checked on a Plain Button
What's happening: A <button> is being used as a toggle. Developer added aria-checked="true", but checked is not a state on the button role.
Fix: Use aria-pressed for press-toggle buttons, or change the role to role="switch" if it's a settings toggle.
Problem: aria-required on a Non-Form Element
What's happening: aria-required is only valid on form-input roles (textbox, checkbox, radio, combobox, listbox, spinbutton, tree, radiogroup, gridcell).
Fix: Move it onto the actual input. Better yet, use the native HTML required attribute.
Problem: Typo in Attribute Name
What's happening: aria-lable, aria-decribedby, aria-haspopup-menu. The browser ignores them silently.
Fix: Add eslint-plugin-jsx-a11y to your build with the aria-props rule enabled — it catches every typo in the attribute name.
Problem: Boolean Attribute With a Non-Boolean Value
What's happening: aria-pressed="yes", aria-expanded="open", aria-checked="1". Screen readers fall back to ignoring the state.
Fix: Always emit the literal strings "true" / "false" (or "mixed" where allowed). In React, pass a JS boolean — React serializes it correctly.
aria-allowed-attr vs aria-valid-attr vs aria-valid-attr-value
All three audits sound similar but catch different bugs. Knowing which fired tells you whether to fix the role, the attribute name, or the value token.
| Audit | What It Catches | Example Failure | Typical Fix |
|---|---|---|---|
aria-allowed-attr | Real attribute, used on a role that does not support it | <button aria-checked="true"> | Change role (e.g. to switch) or drop the attribute |
aria-valid-attr | Attribute name not in the WAI-ARIA spec (typo, made-up) | <img aria-lable="Logo"> | Correct the spelling — usually aria-label, aria-describedby, etc. |
aria-valid-attr-value | Real attribute, but value is not in the allowed token list | aria-pressed="yes" | Use spec tokens: "true" / "false" / "mixed" |
aria-required-attr (related) | A role is missing an attribute the spec marks as required | role="slider" with no aria-valuenow | Add the required state/property for the role |
FAQ
What does the aria-allowed-attr audit check?
It verifies that every ARIA state and property on an element is permitted for that element's role. The WAI-ARIA spec defines a fixed list of supported states and properties for each role, and anything outside that list fails the audit.
Is invalid ARIA a WCAG failure?
Yes. Invalid ARIA almost always maps to WCAG 2.2 Success Criterion 4.1.2 Name, Role, Value (Level A), because the role/state/value triple becomes unreliable. Some misuses also touch SC 1.3.1 Info and Relationships.
Why does WebAIM's data show ARIA correlates with MORE accessibility errors?
Because most ARIA in the wild is misused. WebAIM's 2025 Million homepage analysis found pages using ARIA averaged more detected errors than pages without it — the ARIA was being applied incorrectly. The W3C's First Rule of ARIA exists for exactly this reason: native HTML first, ARIA only when there's no native equivalent.
What's the difference between aria-pressed and aria-checked?
aria-pressed belongs on toggle buttons (Bold, Italic, Mute). aria-checked belongs on roles that represent a selection state — checkbox, radio, switch, menuitemcheckbox, menuitemradio, option, treeitem. Putting aria-checked on a button is the canonical aria-allowed-attr failure.
Will browsers warn me about typos in ARIA attribute names?
No. Unknown attributes (aria-lable, aria-pressed-state) are silently ignored by the HTML parser. The page renders normally and the screen-reader output is wrong. The only reliable way to catch typos is automated linting (eslint-plugin-jsx-a11y), an automated accessibility checker like axe-core, or Chrome DevTools' Issues panel.
Does invalid ARIA affect AI search engines like ChatGPT and Perplexity?
Indirectly. AI answer engines use the accessibility tree and semantic HTML to understand page structure. Broken ARIA produces a noisier accessibility tree, weaker structured signals, and worse rankings in traditional Google search — and AI answer engines preferentially cite pages that already rank well. Clean ARIA helps both audiences.
How do I fix aria-checked="true" on a button?
Pick the right semantics for what the control actually does. If it's a settings toggle, use role="switch" — that role accepts aria-checked. If it's a press-toggle (Bold, Mute), swap to aria-pressed. If it's a real checkbox, use <input type="checkbox"> and skip ARIA entirely.
Conclusion
Allowed-attribute errors are almost always a sign that an element is wearing the wrong role. The fix is rarely "add more ARIA" — it's usually "use the native HTML element" or "change the role to one that actually fits." Once the role matches the behavior, the allowed-attribute list takes care of itself.
Run a Greadme deep scanto see exactly which elements on your site are using disallowed ARIA attributes, which are using attribute names that don't exist, and which are using invalid value tokens — then fix the templates that repeat the same mistake.
