ARIA attribute values must be valid
Last updated:
Related Guides
ARIA attributes must not use invalid or misspelled values
Every aria- attribute must use a permitted value defined for that attribute.
This applies to all ARIA states and properties on interactive and structural UI.
Invalid values confuse assistive technologies and break announced states for many users.
Why It Matters
Assistive technologies rely on exact ARIA values to convey state and relationships. If a value is wrong, the AT may ignore it or announce the wrong state.
People using screen readers, voice control, or switch devices are affected when a toggle reads as off while it is actually on, or when an element is announced without its description.
For sighted keyboard users, invalid values can prevent expected behavior in custom widgets.
Common Causes
- Typos or invented tokens (e.g.,
aria-hidden="rtue"oraria-checked="yes"). - Using the wrong type (e.g., numbers for booleans, commas in ID lists).
- Values not allowed for the role (e.g., unsupported tokens on a given widget).
- ID references that do not exist or are duplicated in the DOM.
- State not kept in sync with UI changes (e.g.,
aria-expandednot updated on toggle). - Copying examples without checking the ARIA spec for allowed values.
How to Fix
- Identify the attribute and check its allowed value types in the WAI-ARIA states and properties reference (use ARIA 1.2).
- Use only permitted tokens, spelled exactly. For booleans use "true" or "false". For tristate controls that support it, use "mixed".
- Keep state in sync. When a control opens, set
aria-expanded="true"; when closed, set it to "false". Update the DOM visibility as well. - Validate ID references. For
aria-controls,aria-labelledby,aria-describedby, and similar, ensure the referenced ids exist, are unique, and are space-separated for lists. - Respect role-specific requirements. Some roles have implicit default values or require certain states (e.g.,
role="switch"usesaria-checkedwith true/false). Do not supply unsupported values. - Prefer native HTML where possible. If you must use ARIA on custom widgets, implement full keyboard and state management.
- Recommendation: use lowercase for tokens, do not localize token values, and avoid setting attributes when the default/implicit value is correct.
- About "undefined": if an attribute supports an undefined state, this usually means omit the attribute to represent "not set". Only use the literal token "undefined" when the specification explicitly allows it for that attribute.
Allowed value types you will encounter:
- true/false (boolean)
- true/false/mixed (tristate)
- true/false/undefined (where undefined differs from false)
- ID reference (single id)
- ID reference list (space-separated ids)
- integer (no fraction)
- number (real number)
- string (free text)
- token (one value from a fixed set)
- token list (space-separated allowed tokens)
WCAG alignment: Incorrect ARIA values commonly fail 4.1.2 Name, Role, Value.
How to Test
Keyboard check (for custom widgets):
- Can you operate the widget with Tab, Enter, and Space?
- Does the ARIA state (e.g.,
aria-expanded,aria-checked) update correctly on interaction?
Screen reader check:
- With NVDA + Firefox or VoiceOver + Safari, navigate to the control.
- Confirm the announced role and state match the visual UI and update as you interact.
Browser and code check:
- Inspect the element in browser DevTools Accessibility panel. Verify the computed role and states; look for warnings about invalid ARIA.
- Confirm every ID in aria-* references a unique element that exists in the DOM.
- Run an automated checker to flag invalid ARIA values, then manually verify.
Mobile/touch check:
- With TalkBack or iOS VoiceOver, focus the control and ensure the state is read correctly as you activate it.
Simple checklist:
- Values are from the allowed set for that attribute.
- ID references exist and are space-separated.
- States change in sync with UI behavior.
- No typos, no invented tokens, no localization of token values.
Good Example
<button type="button" class="accordion-trigger" aria-expanded="false" aria-controls="panel-a" id="trigger-a">Shipping details</button>
<div id="panel-a" role="region" aria-labelledby="trigger-a" hidden>
<p>Orders ship within 2 business days.</p>
</div>
<div role="checkbox" tabindex="0" aria-checked="mixed" id="opt-news">Email preferences</div>
<script>
const btn = document.getElementById('trigger-a');
const panel = document.getElementById('panel-a');
btn.addEventListener('click', () => {
const expanded = btn.getAttribute('aria-expanded') === 'true';
btn.setAttribute('aria-expanded', expanded ? 'false' : 'true');
panel.hidden = expanded;
});
const box = document.getElementById('opt-news');
function toggleBox() {
const v = box.getAttribute('aria-checked');
const next = v === 'mixed' ? 'true' : (v === 'true' ? 'false' : 'mixed');
box.setAttribute('aria-checked', next);
}
box.addEventListener('click', toggleBox);
box.addEventListener('keydown', e => {
if (e.key === ' ' || e.key === 'Enter') { e.preventDefault(); toggleBox(); }
});
</script>Why this is good:
aria-expandeduses only true/false and matches panel.hidden.aria-controlspoints to an existing id.- The checkbox uses only true/false/mixed.
Bad Example
<button type="button" aria-expanded="open" aria-controls="missing-panel">Details</button>
<!-- No element with id="missing-panel" exists -->
<div role="checkbox" tabindex="0" aria-checked="1">Subscribe</div>
<p id="hint1">Enter your 6-digit code</p>
<input type="text" aria-describedby="hint1, hint2" aria-hidden="rtue">What’s wrong:
aria-expanded="open"is not a permitted value.aria-controlsreferences a non-existent id.aria-checked="1"is invalid; only true/false/mixed are allowed.- ID reference list uses commas; must be space-separated and all ids must exist.
aria-hiddenvalue is misspelled and will be ignored.
Quick Checklist
- Use only allowed tokens for each aria-* attribute; avoid typos and invented values.
- Keep ARIA state values synchronized with the actual UI state.
- Provide existing, unique IDs for IDREF/IDREFS attributes; separate lists with spaces.
- Do not localize token values; use standard tokens (recommend lowercase).
- Respect role-specific defaults and required states; remove unsupported attributes.
- Prefer native HTML elements; add ARIA only when necessary and fully supported.
- Verify in DevTools and with screen readers; fix any invalid ARIA warnings.