Today, I learned that an
<input> element (or any other form control) can be disabled
by wrapping in a
fieldset element and disabling the
fieldset. For example:
<form> <fieldset disabled="true"> <input> </fieldset> </form>
The markup above will display an text
input element that cannot be interacted with.
However, there are some intricacies to this, that are perhaps surprising.
disabledcontent attribute on the
inputdoes not get set.
document.querySelector('input[disabled]'); //=> null
inputelement node does not set its
document.querySelector('input').disabled; // false
inputelement is selectable by the
document.querySelector('input:disabled'); //=> <input>
I discovered this while trying to write a test that asserted that an
input element was,
in fact, disabled. When I queried for the
input and checked the
false when I could clearly see in the rendered markup that it looked disabled.
Digging a little deeper, it turns out that “disabled behavior” of a form control can be broken down into 3 things:
- the state, which determines if the user can interact with the element
- the content attribute, which would show up in the HTML
The spec says that the IDL attribute should always reflect the content attribute, but it does not say anything (that I could find, at least) about how to synchronize with the state.
I would normally consider this a bug, but bugs are not errant behavior, bugs are deviations from the spec. In this case, since the spec doesn’t define correct behavior, it is likely that this is not a bug and is up to browser vendors to implement.
- “Properties” on a DOM node are called “IDL attributes”. I learned so much stuff today!