How to fix: Nested interactive elements
Never nest one interactive element inside another, such as a <button> inside an <a> or a link inside a button; restructure them so the controls are siblings rather than parent and child.
What it is
Interactive elements, links, buttons, form fields, and elements with roles like button, link, tab, or menuitem, are meant to be discrete, individually focusable controls. WCAG Success Criterion 4.1.2 Name, Role, Value requires that each control's role, state, and operation be exposed to assistive technology, which is only possible when controls are not tangled inside one another.
Nesting breaks this. The HTML specification does not allow an interactive element to contain another interactive element, so markup like a <button> inside an <a>, or an <input> inside a <label> that is itself a link, is invalid. Browsers attempt to recover from invalid nesting in inconsistent ways, sometimes re-parenting elements, which means the rendered DOM may not even match what you wrote.
The practical result is unpredictable focus and activation. The browser cannot reliably decide which control should receive a click or an Enter keypress, so a tap might fire the outer control, the inner one, or both. Screen readers and other assistive technology announce the combined element ambiguously. The correct structure is always to place the controls side by side as siblings, each with its own clear purpose.
Who it affects & why it matters
Keyboard users are affected directly, because focus order and activation become unreliable: tabbing may land on a control that does not behave as expected, and pressing Enter may trigger the wrong action. Screen reader users hear an ambiguous, doubled-up control whose role and name are unclear.
It also affects touch and switch-device users, who may activate an unintended action when nested hit areas overlap, and it creates subtle bugs for everyone, since the same click can produce different behavior across browsers. Untangling the controls makes activation predictable for all input methods.
Nested interactive elements fail SC 4.1.2, a Level A criterion, the most basic conformance tier, and WCAG 2.1 Level AA (which includes all Level A criteria) is the standard U.S. courts apply to ADA Title III claims. The problem also produces invalid HTML, so it tends to show up in both accessibility and markup-validation reports, an easy, documented finding for a plaintiff's tooling.
Because the affected elements are interactive controls, a card that is a link containing a separate button, a menu item wrapping a link, the failure sits on the parts of the page users most need to operate correctly. With web accessibility lawsuits rising and disproportionately targeting businesses under $25 million in revenue, restructuring the markup so controls are siblings removes a real keyboard barrier and a validity error at once.
How to fix it
- Look for interactive elements that contain other interactive elements, most often a <button> inside an <a>, or a link inside a button.
- Identify the two distinct actions involved (for example, navigate to an article and save it) so each gets its own control.
- Restructure the markup so the controls are siblings inside a non-interactive container such as a <div>, not parent and child.
- Make sure each control has its own accessible name and that the surrounding container is not itself focusable or clickable in a conflicting way.
- Tab through the result to confirm each control is reached and activated independently, then re-scan.
<a href="/article">
Read the full article
<button onclick="save()">Save</button>
</a><div class="card">
<a href="/article">Read the full article</a>
<button onclick="save()">Save</button>
</div>How AccessKnight detects this
AccessKnight builds a selector for interactive elements, a, button, [role="button"], [role="link"], [role="tab"], [role="menuitem"], input, select, and textarea, then checks each matched element to see whether it has an interactive ancestor that also matches that selector. When an interactive element is found nested inside another interactive element, it is flagged once, with the parent element named in the message (for example a <button> inside an <a>). Restructuring the markup so the two controls become siblings rather than parent and child resolves the finding.