Indeterminate Radio Buttons

Published by Chris Coyier

There is a pseudo class selector, :indeterminate, whose job it can be to select radio button inputs which are neither selected (have attribute "checked") or unselected (don't have that). This is a CSS3 selector, which may be in response to the HTML5 spec, which explicitly allows radio buttons to be in this state:

If none of the radio buttons in a radio button group are checked when they are inserted into the document, then they will all be initially unchecked in the interface, until such time as one of them is checked (either by the user or by script).

What's the point of all this? Well... why explicitly allow such bad UI?


Neither choice selected

In a comment here last week, Lee Kowalkowski summed it up nicely:

It's poor UI in my opinion. The most popular option should be checked. If choosing nothing is valid, then a radio group isn't a good fit because the user cannot easily revert the group to its indeterminate state.

It's worth repeating: the user cannot easily revert the group to its indeterminate state.

The HTML4 spec made more sense:

At all times, exactly one of the radio buttons in a set is checked. If none of the <INPUT> elements of a set of radio buttons specifies 'CHECKED', then the user agent must check the first radio button of the set initially.

Since user agent behavior differs, authors should ensure that in each set of radio buttons that one is initially "on".

That second part there, in plain English: Since we know no browsers actually follow this, we are adding this special note to remind authors to take this into their own hands.

In my opinion, we should revert back to the HTML4 spec, but browsers should actually respect it, by forcing at least one radio button to be checked, per group, at all times. Which would then make the :indeterminate pseudo kind of useless.

Remember that radio buttons and select dropdowns are essentially the same thing (can only pick one choice from multiple). So if you need an "unselected" state, perhaps a <select> with a default option of "Choose" would do the trick for you.