When it comes to indulging in a sweet treat, few things are more satisfying than a piece of rich, dark chocolate. But what if eating chocolate could produce the same good feelings as smoking weed…
A checkbox usually has two states: checked and unchecked. But indeterminate checkboxes are in a third state: neither checked nor unchecked. The “checkedness” is not determined.
You have seen these before. The most common reason to have an indeterminate checkbox is when it is controlling a set of checkboxes. When none of the checkboxes are checked, neither is the master checkbox. When all of them are checked, so is the master checkbox. But if some are checked and some are not checked? The master checkbox state cannot be determined—it is indeterminate!
For example, each email in your GMail inbox has its own checkbox to select it. Up top, there is another checkbox. If you check that one, all of the emails are selected. Uncheck to deselect all emails.
If you only select a few emails, then the state of that checkbox cannot be determined. You have neither selected all of the emails, nor have you deselected all of them.
Let’s go!
The first part of the specification we need to understand is this:
This begs the question: What is an “IDL attribute”?
Glad you asked.
In HTML, elements have “content attributes”. These are the attributes that you can set on HTML elements, such as id
and class
.
HTML code is interpreted by the browser on the web page’s first load in order to initialize the DOM. You can use content attributes to set up the initial state on the DOM nodes created by your HTML code.
Later on, if I wanted to get the class name for this element in JavaScript, I could do this:
So to sum up:
Content attributes and IDL attributes often correspond, but not always. In the example above, we see that the content attribute is called class
but the IDL attribute is called className
. The kinds of things you can do with those attributes are also totally different between HTML and JavaScript.
The indeterminate
attribute is one case of an IDL attribute that does not have any corresponding content attribute. This means that the only way to set this state is with JavaScript.
The next important thing we need to understand is this:
This is good to keep in mind. Whether or not a checkbox is checked is always determined; it is always true or false. This matters when you are handling the submitted values from a `form`. It will never submit an indeterminate value.
The good news is that the value of aria-checked
is automatically calculated for you!
I don’t see any reason why you would need to manually set the aria-checked
attribute for a checkbox, unless you are building one from scratch out of div
elements.
Perhaps you think you need this so that you can write a CSS selector for indeterminate checkboxes.
However…
More good news! CSS allows us to select checkboxes in any of the three states using pseudo-classes.
Now that we have pulled back the curtain on tri-state checkboxes, I will end this post with an implementation of a Checkbox
component in React + TypeScript. The benefits of wrapping the native element in a component is that we can support an indeterminate
prop right on the component itself.
The goal is to use the Checkbox
like so, where checked
and indeterminate
are two boolean props on the component.
Here is the full implementation:
Happy hacking!
I would like to extend my gratitude to the following people:
This is my review of the Advancing Women in Product Management (AWIP) Course on Coursera, which I took this over the past 2 months (3 nights a week). Contrary to what its name suggests, it is open to…
I level the cup ignoring the pain traveling arm to shoulder Sifting dry ingredients Dusting off expectations Losing count eyeing the scarred mixing bowl mentally calculating weighty things the mound…