sfw/fix
aria-hidden-focus high

axe "ARIA hidden element must not be focusable or contain focusable elements"

A focusable control sits inside an aria-hidden subtree, so keyboard users tab onto an element screen readers don't announce.

What you see

ARIA hidden element must not be focusable or contain focusable elements
Fix all of the following:
  Focusable content should be disabled or be removed from the DOM

What’s actually happening

`aria-hidden="true"` removes a subtree from the accessibility tree but does nothing to the focus order. So a sighted keyboard user tabs into the hidden region and the focus ring lands on an element a screen reader treats as nonexistent — the user is told nothing about where they are. Classic case: an off-screen nav drawer or a closed modal still in the DOM with its links and buttons reachable by Tab.

Common causes

  • A modal, drawer, or dropdown hidden with `aria-hidden` while its buttons and links keep their natural tab order
  • `aria-hidden="true"` placed on a wrapper (a carousel's inactive slide, an accordion's collapsed panel) that still contains live links or form fields
  • A focusable container — something with `tabindex="0"` — that itself carries `aria-hidden="true"`
  • Decorative icons or SVGs marked `aria-hidden` but wrapped in or rendered as a focusable `<a>`/`<button>`
  • Trying to override with `aria-hidden="false"` on a child — it has no effect once an ancestor is hidden

How to fix it

  1. Decide whether the element should be hidden at allIf it's genuinely offscreen/closed, hide it so it leaves both trees: `display:none`, `visibility:hidden`, or the `hidden` attribute. Those remove it from focus order too, which `aria-hidden` alone never does.
  2. If it must stay in the DOM, make the contents unfocusableSet `tabindex="-1"` on every focusable descendant, or `disabled` on form controls. For a closed modal kept mounted, pull its interactive children out of the tab order while it's hidden, then restore them when it opens.
  3. Stop wrapping focusable controls in aria-hiddenMove the `aria-hidden` to the decorative part only. An icon inside a button should carry `aria-hidden="true"` on the `<svg>`, while the button stays visible to both trees with its own accessible name.
  4. For modals, hide the rest of the page insteadThe correct pattern is the inverse: when a dialog opens, put `aria-hidden="true"` on the page background (or use the `inert` attribute / a `<dialog>` element) and trap focus inside the dialog — never hide the dialog while leaving its controls tabbable.

Stop it recurring

Tab through every show/hide state by keyboard, or use `inert` and a native `<dialog>` which manage focus and the accessibility tree together.

Related errors