Reference guide · html-css-js · Published 2026-08-16 · 3 min read
Making elements non-interactive with the HTML inert attribute
Disable interaction on a subtree with the HTML inert attribute, and compare it with disabled and aria-hidden for modals and paused UI.
- ·What inert does
- ·Inert versus alternatives
- ·Use it for modals
The HTML inert attribute removes a whole subtree from user interaction and from the accessibility tree. When you put inert on an element, everything inside it cannot be clicked, focused, tabbed into, or perceived by assistive technology, and it cannot be selected by find-in-page or text selection, all at once. It became baseline newly available in 2023 (Widely Available by late 2025), so it is safe to use for modal and paused-state UI.
What inert does
Setting the boolean inert attribute toggles the inert behaviour for that element and its descendants.
<div inert>
<button>Cannot be clicked</button>
<a href="#">Cannot be tabbed to</a>
</div>
The browser makes the subtree unfocusable, unclickable, and hidden from assistive technology in one step. It also makes the content unselectable and removes it from sequential focus navigation. Unlike a per-element disabled, it is subtree-wide, so a container with inert neutralises every interactive child even if the child itself is not marked. This is exactly the behaviour you want for the background of a modal, where nothing behind the dialog should steal a click, tab, or the focus of assistive tools while the dialog is open.
It is a real attribute with real focus semantics, so read it as a behaviour toggle rather than a cosmetic class. Removing it returns the subtree to full interactivity immediately.
Inert versus alternatives
Choose the right primitive for the job:
inertfor making a whole container, such as background content, non-interactive for the duration of a state (a modal open).disabledfor individual form controls you do not want submitted or edited, such as a submit button while a request is in flight. See the accessible forms article for pairing disabled controls with labels and states.aria-hidden="true"only hides content from the accessibility tree; it does nothing to stop clicks, focus, or tab order, so it is the wrong tool alone for blocking interaction.inertis the pairing that also removes focus and pointer behaviour.visibility: hiddenordisplay: noneremoves the content from layout entirely, which is heavier thaninertwhen you want a subtree present but inactive.
The familiar and correct combination for a modal is inert on the background plus a dialog or focus-trapped panel in front, so the only interactive content is the dialog and its controls.
Use it for modals
The canonical pattern is toggling inert on the page background when a dialog opens, then removing it when it closes:
const dialog = document.querySelector('dialog');
const page = document.querySelector('#app');
dialog.showModal();
page.inert = true;
dialog.addEventListener('close', () => {
page.inert = false;
});
The native showModal() dialog already does focus trapping and blocks interaction with the rest of the page, so inert on the background is a belt-and-braces addition for a custom overlay or when you open a non-modal dialog and still want the background frozen. Do not put inert on the focused element itself: that would unfocus and hide the control you mean to keep usable.
Because it is boolean, remember that inert="false" present still counts as true; toggle the property in JavaScript (set the boolean .inert), not the string attribute, to avoid the classic "I set it to false but it is still inert" trap. The semantic elements guide and the accessible forms guide give the surrounding constructors, and the dialog article covers the full native focus-trap behaviour that inert supplements but does not replace.