# axe-core nested-interactive error button inside link - how to fix it

## TL;DR

Un-nest the controls: a button inside a link (or a link inside a button) must become siblings, or one of them must stop being interactive. Restructure the card so the link wraps only the title text and the button sits beside it. One line of why: nested interactives create ambiguous keyboard and screen reader behavior, focus can only land on the outer one and the inner one becomes unreachable or double-announced.

## The error, verbatim

```text
{
  "id": "nested-interactive",
  "impact": "serious",
  "help": "Interactive controls must not be nested",
  "nodes": [
    { "target": ["a.card button.save"], "failureSummary": "Fix any of the following: Element has focusable descendants" }
  ]
}
```

## Fix it step by step

### Step 1: Reproduce on one page

```bash
npx @axe-core/cli https://example.com --rules nested-interactive --save axe-nest.json
```

Expected: Violations array contains nested-interactive with the nested control selectors.

### Step 2: List the nested pairs

```bash
node -e "const r=require('./axe-nest.json'); r.violations[0].nodes.forEach(function(n){console.log(n.target.join(' '))})"
```

Expected: Selectors showing the outer and inner interactive elements.

### Step 3: Find the card components in source

```bash
rg -n --glob '*.{jsx,tsx,vue}' 'card' src/components | head -20
```

Expected: Points at the card or tile components with the nested structure.

### Step 4: Un-nest and re-scan

```bash
npx @axe-core/cli https://example.com --rules nested-interactive
```

Expected: Exit code 0, 0 violations. Keyboard test: tab reaches both the link and the button independently.

### Step 5: Gate the rule in CI

```bash
npx @axe-core/cli https://example.com --exit | tail -3
```

Expected: Non-zero exit while any violation remains; add this command to CI so the fix never regresses.

## When to use this skill

- Your axe-core report lists this exact rule id under violations
- You are clearing automated WCAG 2.1 AA failures before a release or audit
- A CI a11y gate (pa11y-ci, lighthouse CI, cypress-axe) is red because of this rule

## When NOT to use this skill

- The issue only shows up in manual screen-reader testing and axe reports zero violations for the rule
- You are doing a full manual WCAG audit, this skill covers the single automated rule only
- The page is a third-party embed you cannot edit, flag it to the vendor instead

## Compatibility

axe-core 4.8+ (rule nested-interactive, WCAG 4.1.2). Same rule in axe DevTools. Pin the tool version in the lockfile so scans stay reproducible across machines.

## Variant phrasings

### element has focusable descendants axe

The failureSummary wording, same un-nesting fix.

### button nested inside anchor tag

The classic card pattern: whole card is a link with a button inside.

### axe DevTools flags the same rule

The browser extension runs the same rule engine; fix once and it clears in every runner.

## Why it happens

Clickable cards make the whole card an anchor for mouse users, then add a real button inside for actions like save or dismiss. HTML forbids interactive content inside anchors and buttons, and browsers handle the nesting inconsistently: the inner control may be unfocusable or may trigger both actions. Axe flags any focusable descendant of a link or button. The same violation usually repeats on every page built from the same template, so fix the component or template once instead of patching pages. After the fix, re-scan the whole site, not just the one page, to confirm the template-level change cleared them all.

## Edge cases

- The stretched-link pattern (link covering the card via CSS, button as a sibling above it) is the standard accessible fix.
- If the inner action navigates, make it a second link as a sibling, not a button inside the link.
- Divs with click handlers nested inside links also fail, the rule covers role-based interactives too.
- Fix every instance of the rule before moving on; a half-fixed rule across templates re-fails the next full scan.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_jopU-QHzsCLIJwzbDKUJww
