Interactive controls must not be nested
Rule
nested-interactive· ARIA · impact serious · Static + live
Why it matters
A control inside another control (a link inside a button, a button inside a link) creates one tab stop with two conflicting actions: screen readers announce only one of them, and keyboard or AT activation becomes unpredictable. Native-in-native nesting is invalid HTML and fails; nesting inside a role-based widget (an explicit interactive ARIA role) warns, because a custom widget may legitimately manage inner focus itself. Containers that are merely focusable — a bare tabindex="0" scroll region, an ARIA 1.1 combobox wrapping its own textbox — are not interactive hosts. Interactive content inside role="gridcell" is exempt (grids manage focus per cell).
How to fix
Restructure so each control stands alone — place the link next to the button, or merge them into a single control with one action.
Example
<button>Save <a href="/help">Help</a></button>
<button>Save</button> <a href="/help">Help</a>
Example
<a href="/product"><button>Buy now</button></a>
<a href="/product">Buy now</a>
Example
<div role="button" tabindex="0">Open <a href="/details">details</a></div>
<table role="grid"><tr><td role="gridcell" tabindex="0"><button tabindex="-1">Edit</button></td></tr></table>
Role-based nesting is a warning (the widget may manage inner focus); gridcell content is exempt entirely.
Example
<div role="link" tabindex="0">Docs <button>Copy</button></div>
<div tabindex="0" role="region" aria-label="Code sample"><pre>npm install</pre><button>Copy</button></div>
A bare tabindex="0" container (keyboard-scrollable region) and the ARIA 1.1 combobox wrapper are focusable, not interactive hosts — only real widget roles and native controls host.
WCAG success criteria
4.1.2 Name, Role, Value — Level A
Every UI component must expose a correct name, role, and (where relevant) state/value to assistive technology.
Standards
This rule contributes to the following standards:
WCAG A EN 301 549 Trusted Tester
| Standard | Criteria |
|---|---|
| EN 301 549 | 9.4.1.2 |
| Trusted Tester v5 | 6.a |