ADA Compliance Professionals

    Nested interactive controls must not include focusable items

    Last updated:

    Who it helps:
    Mobility
    Standard:
    WCAG 2.2 Level A

    Nested interactive controls must not include focusable descendants

    Do not place a focusable element inside another interactive control. This often appears when a button or link wraps another link, input, or any element made focusable with tabindex. Keyboard users encounter empty tab stops, and screen readers may not announce the inner control at all.

    Why It Matters

    Nested focus targets break the expected focus order, causing users to tab to a location where nothing is announced or actionable. That confusion slows or blocks task completion.

    Screen reader users may not hear the inner control’s role or name, or may hear nothing, leading to missed actions. Keyboard-only users can land on an invisible or duplicate focus stop and lose context.

    On touch devices with screen readers, swipe navigation can surface multiple confusing items for what appears to be one control, increasing cognitive load.

    Common Causes

    • Putting an <a> link inside a <button> (or vice versa).
    • Wrapping a full card/link around inner buttons or links.
    • Using role="button" on a container that also includes focusable children.
    • Adding tabindex="0" to icons or spans inside a link or button.
    • Leaving inputs or controls inside summary/details or menu triggers.
    • Using third-party widgets that inject focusable elements into existing buttons or links.

    How to Fix

    1. Keep one interactive control per clickable region.
      • If the parent is the control (e.g., a button), make all children non-focusable.
      • Remove tabindex from child elements and ensure decorative icons are not focusable.
    2. Do not nest anchors or buttons.
      • Convert inner links/buttons to non-interactive elements (span/div) and handle clicks with the parent if needed.
      • Or split the region so each control stands alone, side by side.
    3. Restructure composite components.
      • Cards: either make the whole card one link OR keep separate, clearly separated controls (e.g., a link title and a separate button), not both nested.
      • Menu triggers: place the trigger button separate from the menu items; do not include menu items inside the trigger.
    4. ARIA and semantics.
      • Prefer native controls (<button>, <a href>, <input>, etc.).
      • If using role="button" for legacy reasons, ensure no focusable descendants remain inside.
    5. Styling without extra focus targets.
      • Use CSS for visual treatment. Do not add tabindex or href merely for styling.

    Recommendation: When in doubt, flatten the structure so each focusable control is a sibling, not a descendant of another control.

    How to Test

    Keyboard check

    • Press Tab through the page: each stop should land on a single, announced control.
    • No extra Tab stops inside a button or link.
    • Activate with Enter/Space; action should be clear and consistent.

    Screen reader check

    • NVDA or JAWS (Windows) and VoiceOver (macOS): navigate by Tab and by item/links.
    • Ensure only one control is exposed where one is expected.
    • The control’s role and accessible name are announced once, without silent stops.

    Mobile/touch check

    • iOS VoiceOver or Android TalkBack: swipe through the component.
    • Verify a single actionable item is exposed for a single control.
    • Activation via double-tap triggers the expected action without ambiguity.

    Optional automation

    • Run an automated accessibility scanner and review violations related to nested interactive controls or focusable descendants inside interactive elements.

    Good Example

    A button with an icon that is not focusable, and no nested links:

    HTML
    <button type="button" class="btn-primary">
      <svg aria-hidden="true" focusable="false" class="icon" viewBox="0 0 16 16">
        <path d="M1 8h14"/>
      </svg>
      Create item
    </button>

    Bad Example

    A button that contains a link and an extra focusable span:

    HTML
    <button type="button" class="btn-primary">
      Open
      <a href="/settings" class="inline-link">Settings</a>
      <span tabindex="0" class="focusable-icon">?</span>
    </button>

    Another example: a link wrapping a button:

    HTML
    <a href="/profile" class="card-link">
      <button type="button">Edit</button>
    </a>

    Quick Checklist

    • No anchor inside a button, and no button inside an anchor.
    • Only one focusable element per interactive region.
    • Remove tabindex from child elements inside links/buttons.
    • Decorative elements are not focusable and are aria-hidden if needed.
    • Composite components (cards, menus) expose distinct sibling controls.
    • Screen readers announce one clear role/name per control.
    • Keyboard Tab order has no empty or duplicate stops.