# Elements with aria-hidden='true' must not contain focusable elements.

> Canonical HTML version: https://rocketvalidator.com/accessibility-validation/accesslint/0.16/aria/aria-hidden-focus
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

When an element has `aria-hidden="true"`, it is removed from the accessibility tree. Assistive technologies like screen readers act as though the element and all of its descendants do not exist. However, `aria-hidden` has no effect on keyboard focus. If any focusable element (a link, button, input, or anything with a positive `tabindex`) sits inside an `aria-hidden="true"` container, keyboard users can still tab to it. A screen reader user who reaches that element by pressing Tab will hear nothing, or at best hear a confusing, unlabeled stop in their focus order. They have no way to know what the element is or what activating it would do.

This creates a disconnect between what the keyboard can reach and what assistive technology can perceive. Sighted keyboard users see the focused element, but screen reader users are left navigating blind. The result is an interface that is unpredictable and potentially unusable for people who rely on assistive technology.

## Why this matters

This rule maps to WCAG 2.0 Success Criterion 4.1.2 (Name, Role, Value) at Level A. That criterion requires all user interface components to expose their name, role, and state to assistive technologies. A focusable element hidden with `aria-hidden="true"` has no accessible name or role because it has been explicitly excluded from the accessibility tree, yet it still functions as an interactive control for keyboard navigation. This is a direct violation of 4.1.2.

The issue also conflicts with the fourth rule of ARIA use, which states that focusable interactive elements should not be hidden from assistive technologies.

## How to fix it

There are three approaches, and the right one depends on the situation:

1. **Remove the focusable elements.** If the content inside the `aria-hidden="true"` region is purely decorative and should not be interactive, remove any links, buttons, inputs, or other focusable elements from it entirely.

2. **Add `tabindex="-1"` to focusable descendants.** If the elements must remain in the DOM but should not be reachable by keyboard, set `tabindex="-1"` on each one. This removes them from the sequential focus order (Tab key navigation) while keeping them in the DOM for scripting purposes. Note that native focusable elements like `<a href>` and `<button>` need an explicit `tabindex="-1"` to be removed from the tab order.

3. **Remove `aria-hidden="true"`.** If the content is actually meant to be interactive and accessible, `aria-hidden="true"` should not be there. Remove the attribute so that assistive technologies can perceive the elements.

A common scenario where this problem appears is icon buttons where `aria-hidden="true"` is applied to a wrapper instead of just the icon. Another is modal dialogs that hide background content with `aria-hidden="true"` but fail to also disable focusability of the background controls.

Note that `aria-hidden="false"` on a descendant does **not** override `aria-hidden="true"` on an ancestor. Once a parent is hidden from the accessibility tree, all descendants are hidden regardless of their own `aria-hidden` value.

## Examples

### Incorrect: focusable link inside an `aria-hidden` container

The `<a>` element is focusable by default because it has an `href` attribute. A keyboard user can tab to it, but a screen reader will not announce it.

```html
<div aria-hidden="true">
  <a href="/settings">Settings</a>
</div>
```

### Incorrect: focusable button inside an `aria-hidden` container

The button is in the tab order, but invisible to assistive technologies.

```html
<nav aria-hidden="true">
  <button type="button">Menu</button>
</nav>
```

### Correct: focusable elements removed from tab order with `tabindex="-1"`

Adding `tabindex="-1"` to each focusable descendant removes them from sequential focus navigation, so keyboard users will skip past them.

```html
<div aria-hidden="true">
  <a href="/settings" tabindex="-1">Settings</a>
</div>
```

### Correct: `aria-hidden` applied only to the decorative icon, not the button

The icon font glyph is hidden from assistive technology, but the button itself remains accessible with a proper label.

```html
<button type="button" aria-label="Close">
  <span aria-hidden="true" class="icon-close"></span>
</button>
```

### Correct: non-focusable content inside `aria-hidden`

A `<p>` element is not focusable, so hiding it with `aria-hidden="true"` does not create a keyboard/accessibility mismatch.

```html
<p aria-hidden="true">Decorative tagline text</p>
```

### Correct: focusable element made non-focusable with `disabled`

A disabled input is not part of the sequential focus order, so it can safely exist inside an `aria-hidden="true"` container.

```html
<div aria-hidden="true">
  <input type="text" disabled>
</div>
```

### Correct: focusable element hidden via CSS

An element that is not rendered (via `display: none` or `visibility: hidden`) is not part of the focus order, so there is no conflict with `aria-hidden="true"`.

```html
<div aria-hidden="true">
  <a href="/" style="display: none">Hidden link</a>
</div>
```
