# ARIA Hidden and Inert Content

> Canonical HTML version: https://rocketvalidator.com/glossary/aria-hidden-inert-content
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

ARIA hidden and inert content refers to techniques that remove elements from the accessibility tree or disable their interactivity, preventing screen readers and keyboard users from encountering decorative, redundant, or temporarily irrelevant content such as background page content behind a modal dialog.

Web interfaces often contain elements that should not be exposed to assistive technologies or that should be temporarily non-interactive. A decorative icon next to a button label, a background page behind an open modal, a duplicated heading used only for visual styling: all of these can confuse screen reader users or break keyboard navigation if left accessible. The `aria-hidden` attribute and the HTML `inert` attribute are the two primary tools for handling these situations. They share the broad goal of removing content from user interaction, but they work differently and apply to different scenarios.

`aria-hidden="true"` strips an element and its entire subtree from the accessibility tree. The element stays visible on screen, and users can still click it or tab to any focusable descendants. `inert`, by contrast, is a native HTML boolean attribute that removes the subtree from the accessibility tree *and* blocks all interaction: keyboard focus, pointer events, and text selection. Choosing the right tool depends on whether the content is permanently decorative or temporarily inactive.

## Why ARIA hidden and inert content matters

Screen reader users build a mental model of a page from the accessibility tree. When decorative or irrelevant content leaks into that tree, users hear noise: repeated icon labels, background headings read aloud while a dialog is open, or focusable elements they cannot see.

A common failure is the modal dialog. Sighted users see a dimmed overlay and naturally focus on the dialog. Keyboard and screen reader users, however, can still tab into and read the content behind the overlay unless the developer explicitly removes it from interaction. The consequences are concrete:

- Screen readers announce background content, breaking the expected flow of the dialog.
- Keyboard users can tab to links and buttons hidden behind the overlay, creating a broken focus order.
- WCAG Success Criterion 2.4.3 (Focus Order) and 4.1.2 (Name, Role, Value) are violated.

These problems affect people who use screen readers, keyboard-only navigation, switch devices, and voice control software.

## How ARIA hidden and inert content works

### The `aria-hidden` attribute

Setting `aria-hidden="true"` on an element removes it and all descendants from the accessibility tree. The element remains visible and interactive in the DOM; only its exposure to assistive technologies changes.

Appropriate uses include:

- Decorative icons displayed alongside a text label that already conveys the same meaning.
- Redundant text added for visual layout but duplicated by an existing accessible name.
- Presentational SVGs or images that carry no information.

One strict rule applies: never set `aria-hidden="true"` on a focusable element or on an ancestor that contains focusable elements. If a keyboard user tabs to an element hidden from the accessibility tree, the screen reader has nothing to announce. The user lands on a silent, mystery element, which is a WCAG failure.

Setting `aria-hidden="false"` does not guarantee the element becomes visible in the accessibility tree if an ancestor is already hidden. An element inside an `aria-hidden="true"` container cannot be "un-hidden" by overriding the attribute on the child.

### The `inert` attribute

`inert` is a boolean HTML attribute. When present on an element, it makes that element and all its descendants completely dormant:

- They are removed from the accessibility tree.
- They cannot receive keyboard focus.
- Click and pointer events do not fire on them.
- Text inside them cannot be selected.

This behavior makes `inert` the right choice for background content behind modals, slide-out panels, or full-screen overlays. The attribute should be added when the overlay opens and removed when it closes.

Browser support for `inert` is available in all modern browsers. A polyfill exists for older environments, though its use is decreasing.

### Choosing between `aria-hidden` and `inert`

| Feature | `aria-hidden="true"` | `inert` |
|---|---|---|
| Removes from accessibility tree | Yes | Yes |
| Prevents keyboard focus | No | Yes |
| Prevents pointer interaction | No | Yes |
| Prevents text selection | No | Yes |

Use `aria-hidden` for content that is permanently decorative and should never be announced, regardless of page state. Use `inert` for content that is temporarily irrelevant and should be fully non-interactive while another UI surface has focus.

## Code examples

### Bad example: modal without hiding background content

The background page stays accessible and focusable while the modal is open. Users can tab to the "Browse products" link behind the dialog.

```html
<div class="page-content">
  <h1>Welcome to our site</h1>
  <a href="/products">Browse products</a>
</div>

<div class="modal" role="dialog" aria-labelledby="modal-title" aria-modal="true">
  <h2 id="modal-title">Subscribe to our newsletter</h2>
  <label for="email">Email address</label>
  <input type="email" id="email">
  <button type="submit">Subscribe</button>
  <button type="button" class="close-btn">Close</button>
</div>
```

Although `aria-modal="true"` signals to assistive technologies that the dialog is modal, browser support for actually trapping screen reader navigation with this attribute alone is inconsistent.

### Good example: using `inert` on background content

```html
<div class="page-content" inert>
  <h1>Welcome to our site</h1>
  <a href="/products">Browse products</a>
</div>

<div class="modal" role="dialog" aria-labelledby="modal-title" aria-modal="true">
  <h2 id="modal-title">Subscribe to our newsletter</h2>
  <label for="email">Email address</label>
  <input type="email" id="email">
  <button type="submit">Subscribe</button>
  <button type="button" class="close-btn">Close</button>
</div>
```

Adding `inert` to `.page-content` removes it from the accessibility tree and prevents keyboard focus from reaching anything inside it. When the modal closes, JavaScript removes the attribute to restore normal interaction.

### Bad example: `aria-hidden` on a focusable element

```html
<button aria-hidden="true" onclick="doSomething()">
  Perform action
</button>
```

This button accepts keyboard focus, but no screen reader will announce it. The user lands on a silent, unnamed control.

### Good example: `aria-hidden` on a decorative icon

```html
<button type="button">
  <svg aria-hidden="true" focusable="false" viewBox="0 0 24 24">
    <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/>
  </svg>
  Menu
</button>
```

The SVG is hidden from assistive technologies because the visible text "Menu" already communicates the button's purpose. The `focusable="false"` attribute on the SVG prevents an extra tab stop in older versions of Internet Explorer and Edge Legacy.

### Managing `inert` with JavaScript

```javascript
const modal = document.querySelector('.modal');
const pageContent = document.querySelector('.page-content');
const closeBtn = modal.querySelector('.close-btn');

function openModal() {
  pageContent.setAttribute('inert', '');
  modal.hidden = false;
  modal.querySelector('input, button').focus();
}

function closeModal() {
  pageContent.removeAttribute('inert');
  modal.hidden = true;
}

closeBtn.addEventListener('click', closeModal);
```

This pattern keeps background content fully inert while the modal is open and restores it when the modal closes. It avoids the complexity of manual focus-trap scripts for the background layer, though you still need to manage focus movement into and out of the dialog itself.
