The Old Way of Disabling
The methods of disabling used in the past typically involved the following two approaches:
- disabled attribute
This method is only applicable to form elements. For example, if the disabled attribute is set on an input field, it cannot be edited, the click event will not be triggered, and the data will not be included when the form is submitted.
<input name="author" value="melin" disabled>
For elements like <div>
, <p>
, and <a>
, the disabled attribute does not apply.
However, setting the disabled attribute on an element does not prevent interactions like hover. This means that native tooltips, such as the title attribute, or custom tooltip messages can still be applied to disabled form elements like buttons (as shown in the image below), which is actually a nice advantage.
In contrast, elements with pointer-events: none
cannot have this kind of interaction.
- pointer-events:none
pointer-events: none
disables mouse interactions, including clicks, hover, and other interactions.
However, it does not block keyboard navigation. For example, the input field below can still be accessed via the keyboard, and you can still type content.
<input name="author" value="melin" style="pointer-events:none">
Therefore, pointer-events: none
isn’t truly a complete disabling method.
Its benefit is that it can be applied to any element, making it especially useful for creating “click-through” overlays.
Now, the question arises: Is there a method that can completely disable both mouse and keyboard interactions on any element?
Yes, there is — the inert attribute, which is the main focus of this article.
A more complete solution: the inert attribute.
The word “inert” means inactive, motionless, sluggish, or lifeless.
Setting the inert attribute on an element makes it feel as if it has disappeared from the page. Although it remains visible (with no changes in style), any interaction with it becomes ineffective.
In the past, to disable all controls within a form, we had to use the <fieldset>
element.
Now, we have an alternative: the inert attribute. For example:
<form inert>
<label for="melin" title="author">author</label>
<input name="author" id="melin" value="melin" required>
<p>
<button type="submit">submit</button>
</p>
</form>
At this point, the entire form element, including the text, cannot be clicked, interacted with, or used.
Unlike the disabled attribute, the inert attribute does not apply any styles to the element. Therefore, if no additional CSS is applied, the user will not visually perceive that the form is disabled.
In this case, we can use CSS attribute selectors to target the element and apply the desired styles.
form[inert] {
filter: grayscale(1) opacity(0.6);
}
At this point, the form will appear as shown in the image below:
But it’s not perfect, though.
While the inert attribute is powerful for disabling elements, it becomes difficult to manage if the user wants to know the reason for the disabling (e.g., a hover tooltip), since no interactions can be triggered.
Additionally, determining whether an internal element is disabled is not as straightforward as with the disabled attribute. The disabled attribute has dedicated :enabled and :disabled pseudo-classes for matching, even if the disabled attribute is set on a parent <fieldset>
element.
However, checking if an element is disabled with the inert attribute is less convenient. It can only be done using an attribute selector:
[inert] .my-class {}
Now, Let’s Talk About Compatibility
With Firefox adding support for the HTML inert attribute, now all major modern browsers support this highly effective disabling attribute.
I’ve roughly looked into it: disabling mouse interactions, preventing text selection, and using tabindex=-1
to disable keyboard access, among other methods.
[inert] {
pointer-events: none;
cursor: default;
}
[inert], [inert] * {
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
That concludes this article. Thank you for reading.