148

I know there is an official CSS3 :checked pseudo-class, but is there an :unchecked pseudo-class, and do they have the same browser support?

Sitepoint's reference doesn't mention one, however this whatwg spec (whatever that is) does.

I know the same result can be achieved when the :checked and :not() pseudo-classes are combined, but i'm still curious:

input[type="checkbox"]:not(:checked) {
    /* styles */
}

Edit:

The w3c recommends the same technique

An unchecked checkbox can be selected by using the negation pseudo-class:

:not(:checked)
Community
  • 1
  • 1
Web_Designer
  • 72,308
  • 93
  • 206
  • 262

4 Answers4

139

:unchecked is not defined in the Selectors or CSS UI level 3 specs, nor has it appeared in level 4 of Selectors.

In fact, the quote from W3C is taken from the Selectors 4 spec. Since Selectors 4 recommends using :not(:checked), it's safe to assume that there is no corresponding :unchecked pseudo. Browser support for :not() and :checked is identical, so that shouldn't be a problem.

This may seem inconsistent with the :enabled and :disabled states, especially since an element can be neither enabled nor disabled (i.e. the semantics completely do not apply), however there does not appear to be any explanation for this inconsistency.

(:indeterminate does not count, because an element can similarly be neither unchecked, checked nor indeterminate because the semantics don't apply.)

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • Just to add to this answer that selecting :not(:checked) works perfectly on Chrome, but it doesn't on IE (tested on 9 and 11). – Bruno Finger Jan 20 '15 at 15:40
  • @Bruno Finger: :checked and :not(:checked) should both work on IE, except both of them are equally affected by a bug where changing the checked status does not update the styles of elements being targeted in relation to the checked/unchecked element. – BoltClock Jan 20 '15 at 15:44
52

I think you are trying to over complicate things. A simple solution is to just style your checkbox by default with the unchecked styles and then add the checked state styles.

input[type="checkbox"] {
  // Unchecked Styles
}
input[type="checkbox"]:checked {
  // Checked Styles
}

I apologize for bringing up an old thread but felt like it could have used a better answer.

EDIT (3/3/2016):

W3C Specs state that :not(:checked) as their example for selecting the unchecked state. However, this is explicitly the unchecked state and will only apply those styles to the unchecked state. This is useful for adding styling that is only needed on the unchecked state and would need removed from the checked state if used on the input[type="checkbox"] selector. See example below for clarification.

input[type="checkbox"] {
  /* Base Styles aka unchecked */
  font-weight: 300; // Will be overwritten by :checked
  font-size: 16px; // Base styling
}
input[type="checkbox"]:not(:checked) {
  /* Explicit Unchecked Styles */
  border: 1px solid #FF0000; // Only apply border to unchecked state
}
input[type="checkbox"]:checked {
  /* Checked Styles */
  font-weight: 900; // Use a bold font when checked
}

Without using :not(:checked) in the example above the :checked selector would have needed to use a border: none; to achieve the same effect.

Use the input[type="checkbox"] for base styling to reduce duplication.

Use the input[type="checkbox"]:not(:checked) for explicit unchecked styles that you do not want to apply to the checked state.

Michael Stramel
  • 1,337
  • 1
  • 16
  • 18
  • There are other uses of css selectors where it's useful / expressive though: javascript, automated browser testing – nruth Jun 26 '15 at 14:40
  • 2
    This isn't always possible. Form elements in particular are notorious for not allowing you to revert them to their default look and feel via cascading rules. (Though why anyone would want to give only checked or only unchecked inputs a custom look and feel while leaving the other mint is beyond me.) – BoltClock Sep 30 '15 at 09:54
  • Another case where this isn't possible: More than 2 radio buttons. For example, you may want one style when option#1 is :checked and another when anything else is :checked. The solution is `:not(:checked)` – Navin Dec 11 '15 at 01:08
  • If you were wanting only wanting specific ones styled, why not use a `:first-child`, `:last-child`, or `:nth-child` selector in combination with `:checked`. `:not(:checked)` will not cover the situation you specified unless I am misunderstanding your comment. – Michael Stramel Dec 11 '15 at 19:23
  • @MichaelStramel putting the order of the htmls into the css? nope thanks – inetphantom Jun 12 '19 at 11:28
  • @inetphantom Okay, then apply classes and use those selectors? There are multiple ways to do everything. Each has its own use-case. – Michael Stramel Jun 13 '19 at 01:55
5

There is no :unchecked pseudo class however if you use the :checked pseudo class and the sibling selector you can differentiate between both states. I believe all of the latest browsers support the :checked pseudo class, you can find more info from this resource: http://www.whatstyle.net/articles/18/pretty_form_controls_with_css

Your going to get better browser support with jquery... you can use a click function to detect when the click happens and if its checked or not, then you can add a class or remove a class as necessary...

Jeff Wooden
  • 5,339
  • 2
  • 19
  • 24
-2

The way I handled this was switching the className of a label based on a condition. This way you only need one label and you can have different classes for different states... Hope that helps!

Daniel Ram
  • 352
  • 2
  • 6