Indeterminate Checkboxes

Avatar of Chris Coyier
Chris Coyier on (Updated on )

Checkbox inputs can only have two states: checked or unchecked. They can have any value, but they either submit that value (checked) or don’t (unchecked) with a form submission. The default is unchecked. You can control that in HTML like this:

<!-- Default to unchecked -->
<input type="checkbox">

<!-- Default to checked, XHTML -->
<input type="checkbox" checked="checked" />

<!-- Default to checked, HTML5 -->
<input type="checkbox" checked>

Visually, there are actually three states a checkbox can be in: checked, unchecked, or indeterminate. They look like this:

Here are some things to know about indeterminate checkboxes:

You can’t make a checkbox indeterminate through HTML. There is no indeterminate attribute. It is a property of checkboxes though, which you can change via JavaScript.

var checkbox = document.getElementById("some-checkbox");
checkbox.indeterminate = true;

or jQuery style:

$("#some-checkbox").prop("indeterminate", true); // prop is jQuery 1.6+

The indeterminate state is visual only. The checkbox is still either checked or unchecked as a state. That means the visual indeterminate state masks the real value of the checkbox, so that better make sense in your UI!

Like the checkboxes themselves, indeterminate state looks different in different browsers. Here’s Opera 11.50 on Mac:

Use Case

The reason I’m writing this is because I just had a use case come up for this state: nested checkboxes. Each checkbox may have child checkboxes. If all those children are checked, it may be checked. If none are checked, it is unchecked. If some of them are checked, then it’s in an indeterminate state (in this case symbolically meaning “partially” checked).

Here’s that in jQuery:

See the Pen Indeterminate Checkboxes by Chris Coyier (@chriscoyier) on CodePen.

Here’s an alternate jQuery version from TheNotary.

And here’s a plain JavaScript version from Jakob Eriksen:

See the Pen
Indeterminate Checkboxes (Vanilla JS)
by jakob-e (@jakob-e)
on CodePen.

And a couple of alternate approachs from Alvaro Montoro , Bramus, Gridbuilder, Lewin Probst, and Jason Wilson.

Using StimulusJS from Stephen Margheim:

See the Pen
checkbox family
by Stephen Margheim (@smargh)
on CodePen.

Rotating amongst the states

Jon Stuebe was messing around with the idea of rotating the state between unchecked, indeterminate, and checked with a click. Here’s some jQuery to do that:

var $check = $("input[type=checkbox]"), el;
$check
   .data('checked',0)
   .click(function(e) {
       
        el = $(this);
                
        switch(el.data('checked')) {
            
            // unchecked, going indeterminate
            case 0:
                el.data('checked',1);
                el.prop('indeterminate',true);
                break;
            
            // indeterminate, going checked
            case 1:
                el.data('checked',2);
                el.prop('indeterminate',false);
                el.prop('checked',true);                
                break;
            
            // checked, going unchecked
            default:  
                el.data('checked',0);
                el.prop('indeterminate',false);
                el.prop('checked',false);
                
        }
        
    });

See the Pen Rotate Through Indeterminate Checkboxes by Chris Coyier (@chriscoyier) on CodePen.

Reader Casual Trash sent me in a library-free and far more succinct version of rotating through all three visual states which utilizes the readonly attribute that checkbox inputs can have.

<!-- Inline click handler, just for demo -->
<input type="checkbox" id="cb1" onclick="ts(this)">
function ts(cb) {
  if (cb.readOnly) cb.checked=cb.readOnly=false;
  else if (!cb.checked) cb.readOnly=cb.indeterminate=true;
}

See the Pen Rotate Through Indeterminate Checkboxes by Chris Coyier (@chriscoyier) on CodePen.