ARIA overrides native semantics and can conflict rather than supplement
Aliases: role conflict · native semantics · role=presentation
What it is
A role on a native element is not a caption stacked on top. It replaces the role the host language already exposed. <button role="heading"> becomes a heading in the accessibility tree and stops being a button; <h2 role="none"> drops heading semantics. That mechanism is ARIA role override. The author thinks they are supplementing; the tree performs a swap. Native keyboard behaviour, default name computation, and the reader’s element lists then follow the new role, or get stuck in the gap where it still looks like a button and no longer is one.
The point is how override happens and what conflict looks like — not the selection slogan “use native when you can.”
Why it happens
Accessibility mapping looks at an explicit role first, then the host default. A non-empty explicit value drops the default; there is no merge into “button and heading.” role="presentation" / none is deliberate deletion; other roles are reassignment. Conflict is what remains of the host after reassignment: <a role="button"> still activates on Enter, Space may not, yet the reader waits for Space under the button contract; <button role="link"> is the inverse. Name computation can change slots too: buttons eat descendant text; some roles switch to aria-label or stop treating descendants as the name.
The second layer is the reader’s indexes. Users jump with B for buttons, H for headings, F for forms. After override, the element vanishes from its old list, appears on another, or on neither. Visually it is the same control; browse-mode shortcuts no longer land on it.
Studying it
Minimal cells: a native button; the same button with role="link"; an h2 with role="button"; a button with role="presentation". Read the role in the inspector, find it with NVDA’s element shortcuts (B / H / K), then try Enter and Space. VoiceOver’s rotor is a second index; log it too.
Independent variables: host element, explicit role, whether presentation.
Dependent variables: role on the tree, which shortcut list it belongs to, whether Enter/Space still fire, whether the computed name changed source.
Where it stops holding
A few patches are intentional overrides: a nameless container turned into region, or role="text" to repair fragmented characters. role="presentation" on a table tears down a layout table; that is deletion, not reassignment, and cell semantics of descendants disappear with it — a wider blast radius than retagging one button. After ARIA 1.2 some roles are invalid on some elements; engines may ignore rather than override, which looks like “writing it did nothing.” SVG and custom elements start with weak default roles, so override hurts less — which does not license writing anything.
Applying it
- Do not write a different
roleon an element that already has the correct host role in order to “enhance” it. - When reassignment is required, fulfil the new role’s contract (name, state, keyboard) and accept that it will disappear from the old shortcut list.
- When using
presentation/noneto unwrap layout tables or decorative lists, check whether descendants still need cell or list-item semantics; if they do, do not unwrap that far. - How to check: in the inspector, see whether the role is still the host default. Then find the control in NVDA’s B and H lists — on the wrong list, or on neither, override has already reindexed it. Finally press Enter and Space; behaviour that does not match the new contract is conflict, not a supplement.
Related
- Same group: J5.11.1 Relationship attributes must point at elements that actually exist · J5.11.2 Misused live regions interrupt speech with secondary noise · J5.11.4 ARIA cannot add keyboard behavior an element does not already have
- Nearby: J5.03 ARIA supplement · J5.02 Accessibility tree and roles
- Search terms:
ARIA role override·role conflict·presentation