Non-Interactive Role On An Interactive Element
ID |
javascript.jsx_interactive_element_non_interactive_role |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
JavaScript |
Tags |
accessibility, jsx, reliability |
Rationale
An interactive element keeps its behaviour whatever role it claims: the button is still clickable, the link still navigates, both are still in the tab order. Only the announcement changes, and it changes to something that says the element does nothing. A screen reader user is told this is a heading, or a decoration, and has no reason to activate it — the control becomes invisible while remaining reachable by Tab, which is the worst of both.
<button role="heading" onClick={open}>Details</button> // FLAW - announced as a heading
<a href="/x" role="presentation">Home</a> // FLAW - a link with no semantics
<button onClick={open}>Details</button> // OK
<button role="tab" onClick={open}>Details</button> // OK - still a control
<h2><button onClick={open}>Details</button></h2> // OK - heading around the control
<a role="heading" aria-level="2">Details</a> // OK - no href, so not a control
role="presentation" and role="none" are the sharpest form of this: they ask for the semantics to
be stripped, and on a focusable element the specification says that request is ignored, so the
markup states an intent the browser will not honour.
The elements judged are the interactive controls: button, select, textarea, summary and
details; a and area when they carry an href; and input of any type but hidden. Roles
whose interactivity depends on their container, and group, the implicit role of details, are
excluded.