Skip to content

Test your website now

Free, no card. We read only public pages.

Run free audit →

Accessibility · WCAG 4.1.2 level A

Interactive Controls Must Not Be Nested: Separate Actions

Fix nested interactive controls. Separate navigation and actions, preserve keyboard access and focus, and inspect rendered semantics instead of masking clicks.

Published · Updated

What the check tests

Check
a11y.axe.nested-interactive - Interactive controls must not be nested
Passes when
Ensure interactive controls are not nested as they are not always announced by screen readers or can cause focus problems for assistive technologies
Scope
graded on every page crawled
Conformance
WCAG level A
Fix effort
small - under an hour

In one paragraph

Interactive controls must not be nested means a tested control contains another focusable interactive element in a structure the rule rejects. Separate the actions into appropriate sibling controls and keep their names, focus order, and activation behaviour clear. Event suppression or removing an inner element from the tab sequence does not repair invalid semantics. Inspect the rendered DOM because browser parsing can change the source structure.

Why it matters

A card that navigates while also containing a favourite button presents two separate user actions. Wrapping both in a button or another incompatible interactive element can obscure one action in the accessibility tree or make activation ambiguous.

Some widget roles make descendant semantics presentational, which is especially problematic when a descendant remains focusable. Behaviour varies by browser and assistive technology; do not promise every user sees exactly the same failure or that every interactive container behaves identically.

HTML validity and the particular axe selector are separate. Nested anchors or a button inside an anchor can be invalid or problematic even when a specific version of one rule does not report the case. A clean result cannot approve every clickable-card design.

How WebAuditOS evaluates this finding

The supplied nested-interactive integration looks for focusable descendants inside applicable controls whose children are expected to be presentational. It describes coverage limits around link containers and distinguishes focusability from ordinary tab sequence participation.

Serious impact maps to high severity in the supplied report. Exact selectors and applicability need verification against the deployed axe version. A tabindex=-1 change does not reliably remove the semantic problem, and unreported DOM or dynamic states remain outside what this snapshot establishes.

How to fix it

  1. Identify every distinct action in the component. Decide which should navigate with a real link and which should change interface state with a button. Do not turn all actions into one handler merely to avoid nested markup.
  2. Inspect the rendered DOM and computed roles. Invalid HTML can be restructured by the parser, so source indentation is not reliable evidence of the final relationship.
  3. Use a noninteractive container with separate named controls. For example:
<article>
  <h2><a href="/products/blue-scarf">Blue scarf</a></h2>
  <button type="button">Save blue scarf</button>
</article>

This illustrates separation, not a complete saved-state implementation. A toggle needs appropriate consistent naming and state behaviour.

  1. If a larger link hit area is required, consider an established stretched-link design with independent controls above it in the pointer stacking order. Test selection, context menus, focus visibility, and overlap. A CSS overlay is not automatically accessible simply because the DOM is separated.
  2. Remove redundant outer focus and click handling where the individual controls now supply the actions. Otherwise the card can still create duplicate keyboard stops or trigger unexpected navigation.
  3. Do not use stopPropagation as the sole fix. It can alter pointer event behaviour while leaving naming and semantics invalid. Likewise, hiding an interactive child from assistive technology while leaving it focusable creates another problem.
  4. Test keyboard order, Enter and Space behaviour as applicable, pointer activation, touch, and expected new-tab behaviour for links. Check focus after deletion, dialog opening, or another state-changing action.
  5. Rescan and inspect neighbouring cards and modal states manually. Include nested-link cases and custom widget structures even if this particular rule's coverage omits them.

What the fix can break

Separating controls can change event delegation and card-wide hover styling. Adjust handlers and CSS deliberately so selecting Save does not also navigate.

Stretched overlays can cover other controls or prevent text selection. Keep independent hit areas and visible focus understandable at every responsive breakpoint.

Do not replace several useful controls with an inaccessible generic div and an ARIA role. Native semantics usually make navigation and actions easier to implement and maintain correctly.

Questions

Does tabindex=-1 fix an inner control?

No universal guarantee follows. It can remain focusable programmatically or through other interaction and retain the invalid relationship.

HTML does not support ordinary nested anchor navigation. Inspect the resulting DOM and redesign separate destinations.

Will stopping click bubbling solve the accessibility issue?

Not by itself. Semantic relationships, accessible names, and keyboard behaviour still need correction.

Review button names, link names, and the automation limits guide.

What severity does this get in the report?

High. An axe finding takes its severity from the impact axe reports for the element that failed, and the report maps critical and serious to high, moderate to medium, minor to low. This rule is declared serious in axe-core, so a failure arrives as high. That is why the panel above states a conformance level rather than a severity - for other axe rules it depends on what failed.

Standards and sources

In the report

Test this on your own site

Every scan runs a11y.axe.nested-interactive on every page it crawls, on every plan. The finding carries this id, so a line in a report can be matched to the explanation above - and the free scan needs no account.