"inert" attribute


Ah, yes–I must have used the wrong polyfill. The Google one that can be found on npm does not have that functionality. Thanks for the update!


How is this semantically different from the hidden attribute?


hidden affects the visual presentation/rendering; inert does not. Check out the demo page.


sorry about that Marcy! We just published our polyfill to npm: https://www.npmjs.com/package/wicg-inert


hidden affecting visual presentation / rendering is just a matter of applying a different CSS rule (it’s perfectly valid to set a non-none display rule on hidden, though it’s admittedly likely to conflict with the common author-side pattern of including a [hidden] {display: none !important} as part of a page’s base styles) than the suggested rendering by the user-agent; its semantic definition for interaction seems very similar to inert:

When specified on an element, it indicates that the element is not yet, or is no longer, directly relevant to the page’s current state, or that it is being used to declare content to be reused by other parts of the page as opposed to being directly accessed by the user.


Also, the terminology conflicts with the existing meaning of “inert” to refer to DOM content that is not evaluated beyond parsing, ie. the “inert” content of the <template> tag.


Since hidden is typically implemented only using CSS, if you override the CSS styles you also override its behaviour - there is no other behaviour defined in the spec.


A project is likely to use both hidden and inert alongside each other; overriding one for the purpose of the other sounds messy. Inert and hidden serve different purposes–hidden in my experience is a shortcut to CSS display: none, while inert is necessary to create a backdrop for modal dialogs, menus and offscreen contexts that don’t impact the visual design or allow user interaction. This distinction highlights the support gap we are looking to fill with inert.


What about just expanding the disabled attribute to be a global attribute that could be applied to any element, to denote these semantics?


I like this exploration, but I don’t think that’s a workable idea either. disabled form elements etc. have a specific meaning, and are also exposed to assistive technology.


See, that’s the part I’m not wild about about this proposal: it’s going to be equivalent to hidden (semantically) for assistive technologies - the only point on which it differs is for non-assistive use cases, which feels like it’s going to lead to misunderstandings of “oh, inert just lets me disable UI interaction on the element without hiding it” for devs who don’t recognize that there’s a web outside of pointers+screens, meaning that it’d be prone to misuse for elements with semantic importance, whose presence should not be hidden to AT.


Hm, interesting point. Is there a specific scenario you have in mind?


The (mis)use case I’m picturing here is basically anything where I’d use pointer-events: none and user-select: none, like a text-based popup or something else where I’m coding around UA features and think evt.preventDefault() is too much hassle. I discover that there’s this inert attribute, and I go "oh neat, an HTML attribute that’s shorthand for onclick="return false"".


Like, really, the biggest beef I have with this is just bikeshedding that the name inert is semantically bad, which historically leads to disasters around dev (mis)discovery. Like, if it were called something like inaccessible, I’d have less of a problem with it (though I still don’t like how it eats into the use cases for the already woefully-under-and-misused hidden attribute, exacerbating the problems hidden already has around devs not realizing it has aria-equivalent semantic implications).


“inert is necessary to create a backdrop for modal dialogs and blocking contexts that preserve the visual design (while dimmed), but do not allow user interaction.”

So, basically a modal <dialog>? Are there other uses for inert not covered by <dialog>?


The explainer has a few suggestions! https://github.com/WICG/inert/blob/master/README.md#use-cases


Well, to your point, looking at the described use cases, it seems like many of them have the same meaning as disabled form elements (ie. “Form content which is not currently relevant”), and as such, as far as I can tell, should be exposed to AT, the way that disabled form elements are now.



Disabling the entire UI while in an inconsistent state, such as showing a throbber/loading bar during unexpectedly slow loading.

Wouldn’t that be a modal / blockingElement? And:

A slide show or “cover flow” style carousel may have non-active items partially visible, as a preview - they may be transformed or partially obscured to indicate that they are non-interactive.

Wouldn’t the “active item” here be a blockingElement of said non-active elements (ie. this also sounds like a modal)?


Hm I’m not sure about that. A few examples:

An offscreen responsive side-nav. You may not want AT announcing this as it’s not very useful. Another use case is cross-fading elements with interactive content, for example, cross fading two tweets where each might contain anchors. If you have a carousel of tweets it’s not very useful to step through all 10 of them and say “disabled” over and over. However in a form, “disabled, button” can be useful to hear.


I think it’s really only the “form content” example which is potentially controversial there.

Re modal:

  • Yes, a throbber would work well as a “blocking element” if it was the whole page that needed to be made inert; however, you can imagine leaving the toolbars/chrome available while the main content loads
  • No, I don’t think the “cover flow” example is really a blocking element, since conceptually the active element isn’t “blocking” the other elements, and it certainly isn’t blocking the whole document (as it would be if using a blockingElement type interface