Non-interactive Elements with the inert attribute
Elements are interactive in multiple ways; they can be focused, clicked, edited or selected. Assistive technologies such as screen readers also interact with them. What if you wanted to disable all these interactions for a section of your webpage? The inert attribute covers this.
Pre-existing Solutions
The most basic way to disable all interactions is the disabled
HTML attribute, it prevents focus, clicks, edition or selection. However, it only works on form controls, and does not necessarily hide the control from assistive technologies. What if you wanted to do this on elements other than form controls?
To prevent focus, tabindex="-1"
is a popular option, but it isn’t ideal because setting the attribute on a container element will not prevent its children from being focused, and it also does not prevent click-focus with a mouse. If you want to prevent keyboard focus on a whole section, every single focusable element in the section needs the attribute set.
To prevent clicks, the pointer-events: none
CSS property may be an option although, unless you’ve put tabindex="-1"
on the element as well, tabbing to the element and interacting with it is still possible.
To prevent selection, the user-select: none
CSS property is the most common option.
To prevent editing, if you’re using contenteditable
, you would need to manually remove the contenteditable
attribute. If it’s a form control, you need to manually set the disabled
attribute.
All of this is heavy and also does not allow you to hide the section from assistive tools, which may be appropriate when making a whole section non-interactive. It is currently possible to do this by setting aria-hidden="true"
on the relevant section.
This is why the inert
attribute was added to HTML, it is an efficient way to disable all of the interactions above and hide elements from assistive technology.
What is the inert attribute?
The inert
attribute was originally specified in the context of the dialog element about 10 years ago, where the main use-case was making the content behind a modal dialog non-interactive. It was later removed due to a lack of adoption. Recent developer requests lead it to be re-proposed a few years later. However, the main issue with that definition was complexity in interaction with modal dialogs and performance. This is why changes have been made to the standard to use a CSS-based approach to define inert nodes.
According to the HTML specification, when a node is inert:
- Hit-testing must act as if the ‘pointer-events’ CSS property were set to ‘none’.
- Text selection functionality must act as if the ‘user-select’ CSS property were set to ‘none’.
- If it is editable, the node behaves as if it were non-editable.
In addition to the above:
- It is not focusable.
- It behaves similarly to
aria-hidden="true"
for assistive technologies
Example Usage: A Carousel
Let’s build a carousel with multiple pages:
You will notice that you can still interact with links/inputs/etc. from inactive pages. This is undesirable behavior that can be prevented with the inert attribute. In the switchToIndex
method which changes the active page, we can add 2 lines of code that fix this.
this.items
being an array of HTML elements representing each slide, the first line makes every slide inert, and the second line makes the active one non-inert.
switchToIndex(index) {
[...]
this.items.forEach(item => item.inert = true);
this.items[index].inert = false;
}
Notice that we have used the inert
DOM property. When set to a value, it is equivalent to element.toggleAttribute("inert", value)
.
For support for in older browsers, you may want to use a polyfill until the inert
attribute is widely supported.
Finally it is recommended to add a visual cue that a certain element is inert. Let’s make inactive slides less opaque:
.carousel-item[inert] {
opacity: 0.6;
}
Here is the final result in action:
As you can see above, inactive slides are no longer interactive but they are still visible.
Browser support
- Safari 15.5 and Safari Technology Preview 143
- Chrome 102
- Firefox Nightly
Additional resources
In this post, we gave an overview of the new inert attribute. Here are some interesting additional resources you might want to check:
- MDN documentation
- CSS Tricks: Focus management and inert
- HTML specification
- Building better accessibility primitives by Rob Dodson
- Original inert explainer
Feel free to reach out to @therealntim on Twitter for any questions. To report any issues, please file a bug blocking bug 165279.