Articles

The HTML inert Attribute, Explained

The inert attribute removes an element and its children from focus, click handling, and screen reader access in one line, without hiding it visually.

Takina Takina · · 4 min read
Close-up of HTML and CSS code on a screen

The inert attribute marks an element and everything inside it as outside the user’s current interaction — it can’t be focused, clicked, selected, or reached by a screen reader, even though it’s still visible on the page. It’s a single boolean attribute (<div inert>), and it solves a problem that used to require several separate pieces of JavaScript and ARIA working in coordination: making the “background” content behind a modal, drawer, or overlay genuinely unreachable while it’s covered.

The problem it solves

Before inert existed, opening a modal dialog required disabling everything behind it by hand. Visually hiding the background isn’t enough — if the modal is a <div> positioned on top of the rest of the page, a sighted mouse user can’t click through it, but a keyboard user pressing Tab can still cycle focus into buttons and links sitting underneath, and a screen reader user can still navigate into content that’s supposedly “behind” the dialog. Fixing this properly meant walking the DOM, setting tabindex="-1" on every focusable element outside the modal, adding aria-hidden="true" to the background container, and carefully reverting all of it when the modal closed — easy to get wrong, and easy to forget an edge case.

inert replaces that whole dance with one attribute on one container element. Set it on the background wrapper while a modal is open, remove it when the modal closes, and focus, clicks, text selection, and assistive-technology access are all correctly blocked for everything inside — no manual tabindex bookkeeping required.

What inert actually does

An element with inert set:

  • Cannot receive focus, whether by mouse, keyboard Tab navigation, or a scripted .focus() call.
  • Ignores click and other pointer events; event listeners on inert content simply don’t fire.
  • Is excluded from the accessibility tree, so screen readers and other assistive technology skip it entirely — functioning like aria-hidden="true", but also correctly blocking interaction, which aria-hidden alone does not do.
  • Cannot have its text selected or found by the browser’s in-page search (Ctrl+F / Cmd+F).

Critically, none of this changes how the element looks. inert has zero visual effect — the content still renders exactly as its CSS specifies. That’s a deliberate separation of concerns: hiding something visually is CSS’s job (display: none, visibility: hidden), while making it non-interactive is what inert is for. You typically want both together for a fully hidden background, but you sometimes want only one — a dimmed, disabled background panel that’s still visible but unreachable is exactly the case inert was designed for.

A basic modal pattern

<div id="page-content" inert>
  <!-- background content: nav, main page body -->
</div>

<dialog open>
  <p>Are you sure you want to continue?</p>
  <button>Cancel</button>
  <button>Confirm</button>
</dialog>

Toggling inert is as simple as adding or removing the attribute in JavaScript:

pageContent.inert = true;   // disable the background
pageContent.inert = false;  // restore it when the modal closes

The native dialog element actually handles most of this automatically when opened with .showModal() — the browser makes everything outside the top layer inert on your behalf. inert becomes something you reach for explicitly when you’re building a custom overlay, drawer, or multi-step wizard that doesn’t use <dialog>, or when you need to disable a section of the page that isn’t a modal at all — a form panel mid-submission, or a sidebar during a blocking operation.

inert vs the alternatives

It’s worth being precise about what inert replaces and what it doesn’t:

  • disabled only applies to form controls (buttons, inputs, selects) and only blocks interaction with that specific element — it doesn’t cascade to children the way inert does, and it has no effect on non-form elements like <div> or <section>.
  • aria-hidden="true" removes an element from the accessibility tree, which hides it from screen reader users, but it does nothing to stop mouse clicks or keyboard focus from reaching it — a sighted keyboard user can still tab into content marked aria-hidden, which is a well-known accessibility bug pattern. inert fixes that gap by blocking both interaction and accessibility-tree visibility with one attribute.
  • tabindex="-1" applied recursively removes elements from the tab order one at a time, but it’s manual, has to be applied to every focusable descendant individually, and does nothing about pointer events or accessibility-tree exposure on its own.

inert is the only one of the four that correctly covers all three concerns — focus, pointer interaction, and assistive-technology access — for an entire subtree with one line of markup.

Nesting and dynamic toggling

inert is inherited by the whole subtree automatically — you only need to set it on the outermost container you want disabled, not on every descendant individually, and it composes cleanly with elements that are already non-interactive for other reasons. Toggling it is cheap enough to do on every open and close of an overlay, which matters because leaving stale inert attributes around (or forgetting to remove one) silently locks users out of content that should be reachable again. Treat it the same way you’d treat any state you set for the duration of a UI mode — set it when the mode starts, and reliably clear it when the mode ends, including on error paths that might otherwise skip your normal close handler.

The takeaway

inert disables focus, clicks, and screen reader access for an element and its children in a single attribute, without touching how it looks. It’s the right tool for background content behind a modal, an overlay, or any UI region that should be visible but temporarily unreachable, and it removes an entire category of manual tabindex and aria-hidden bookkeeping that accessible overlay components used to require. Reach for it whenever “still on screen, but not interactive” is exactly the state you need.

Takina Takina · · 4 min read

Semantic HTML Elements Explained

Semantic HTML elements like nav, article, and main describe meaning, not just appearance, improving accessibility and SEO. How to use them.

#Accessibility #Web Development #Frontend
Takina Takina · · 4 min read

The HTML dialog Element Explained

The native dialog element gives you modals and popovers with built-in focus trapping and accessibility, no JavaScript library required. Here's how it works.

#Accessibility #Web Development #Frontend
Takina Takina · · 4 min read

What Is Web Accessibility (a11y)? A Practical Guide

Web accessibility (a11y) means building sites usable by people with disabilities. The core principles, semantic HTML, ARIA, and common patterns.

#Accessibility #Web Development #Frontend