Skip to content

The inert Attribute

Global Attribute

The inert attribute makes an element non-interactive by preventing all user interactions including clicks, focus, and selection, while keeping the element visible. It’s particularly useful for modal dialogs, disabled sections, and when you need to temporarily disable parts of your interface.

<element inert>Content</element>
ValueDescription
Boolean (no value)Element and its descendants become non-interactive
Result
Result
Result
Result

When an element has the inert attribute:

  1. Cannot be clicked: All mouse/touch events are ignored
  2. Cannot be focused: Tab key skips inert elements
  3. Cannot be selected: Text selection is disabled
  4. Cascade to children: All descendants become inert
  5. Visible: Element remains visible (unlike hidden)
  6. Accessibility: Removed from accessibility tree
/* Browser default styles (conceptual) */
[inert] {
/* Inert elements are not focusable */
/* Inert elements cannot receive pointer events */
/* Inert elements are not exposed to assistive technology */
}
<!-- disabled: Only works on form elements -->
<button disabled>Can't click</button>
<input disabled>
<!-- inert: Works on any element, including containers -->
<div inert>
<button>Can't click</button>
<a href="#">Can't click</a>
<input type="text">
</div>
<!-- pointer-events: none - Only prevents mouse/touch -->
<div style="pointer-events: none">
<button tabindex="0">Can still be focused with keyboard!</button>
</div>
<!-- inert - Prevents all interactions -->
<div inert>
<button tabindex="0">Cannot be focused at all</button>
</div>
<!-- hidden: Element not visible -->
<div hidden>
<p>You can't see this</p>
</div>
<!-- inert: Element visible but not interactive -->
<div inert>
<p>You can see this but can't interact with it</p>
</div>

The primary use case for inert is modal dialogs:

function openModal() {
// Make background inert
document.querySelector('main').inert = true;
document.querySelector('nav').inert = true;
// Show modal
modal.classList.remove('hidden');
modal.focus();
}
function closeModal() {
// Remove inert
document.querySelector('main').inert = false;
document.querySelector('nav').inert = false;
// Hide modal
modal.classList.add('hidden');
}

Make it obvious that content is inert:

[inert] {
opacity: 0.6;
filter: grayscale(50%);
cursor: not-allowed;
user-select: none;
}
/* Or use blur for background content */
.background[inert] {
filter: blur(3px);
opacity: 0.8;
}

Prevent interaction during async operations:

async function submitForm() {
const form = document.getElementById('form');
// Disable form
form.inert = true;
showLoadingSpinner();
try {
await saveData();
} finally {
// Re-enable form
form.inert = false;
hideLoadingSpinner();
}
}

Visually show locked features:

<div class="feature-card" inert>
<div class="upgrade-badge">
🔒 Premium Feature
</div>
<h3>Advanced Analytics</h3>
<p>Unlock detailed insights...</p>
<button>View Reports</button>
</div>

Disable sections during specific states:

// Disable payment section until shipping address is complete
if (!shippingAddress.isComplete()) {
paymentSection.inert = true;
} else {
paymentSection.inert = false;
}

Elements with inert:

  • Are removed from accessibility tree
  • Cannot be navigated to with screen reader shortcuts
  • Are not announced to screen readers
<!-- Screen reader will skip this entire section -->
<div inert>
<h2>Section Title</h2>
<p>Content that screen readers won't announce</p>
<button>Inaccessible button</button>
</div>

When making content inert, ensure focus is in the right place:

function openDialog() {
// Make background inert
mainContent.inert = true;
// Show dialog
dialog.removeAttribute('hidden');
// Move focus to dialog
dialog.focus();
}

Inert elements are skipped during Tab navigation:

<button>Button 1</button>
<div inert>
<button>Button 2 - Skipped by Tab</button>
<a href="#">Link - Also skipped</a>
</div>
<button>Button 3</button>
<!-- Tab goes: Button 1 → Button 3 -->
const element = document.getElementById('myElement');
// Make inert
element.inert = true;
element.setAttribute('inert', '');
// Remove inert
element.inert = false;
element.removeAttribute('inert');
// Check if inert
if (element.inert) {
console.log('Element is inert');
}
// Toggle
element.inert = !element.inert;
if ('inert' in HTMLElement.prototype) {
console.log('Inert attribute is supported');
} else {
// Load polyfill
console.log('Need polyfill');
}
<!-- For browsers without native support -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/inert.min.js"></script>
class Modal {
constructor(element) {
this.modal = element;
this.background = document.querySelector('main');
}
open() {
this.background.inert = true;
this.modal.removeAttribute('hidden');
this.modal.querySelector('button').focus();
}
close() {
this.background.inert = false;
this.modal.setAttribute('hidden', '');
}
}
const steps = document.querySelectorAll('.step');
function goToStep(stepNumber) {
steps.forEach((step, index) => {
if (index === stepNumber) {
step.inert = false;
step.hidden = false;
} else {
step.inert = true;
step.hidden = true;
}
});
}
function openDrawer() {
drawer.classList.add('open');
mainContent.inert = true;
}
function closeDrawer() {
drawer.classList.remove('open');
mainContent.inert = false;
}
function showLoading() {
document.body.inert = true;
loadingOverlay.hidden = false;
}
function hideLoading() {
document.body.inert = false;
loadingOverlay.hidden = true;
}
BrowserSupportNotes
Chrome102+Native support
Firefox112+Native support
Safari15.5+Native support
Edge102+Native support
IENo support (use polyfill)
<!DOCTYPE html>
<html>
<head>
<!-- Load polyfill for older browsers -->
<script>
if (!('inert' in HTMLElement.prototype)) {
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/inert.min.js';
document.head.appendChild(script);
}
</script>
</head>
<body>
<div inert>
Content that works in all browsers
</div>
</body>
</html>
  • hidden - Hide elements completely (not visible)
  • disabled - Disable form controls specifically
  • aria-hidden - Hide from screen readers only
  • aria-modal - Indicate modal dialog (use with inert)