-1

What CSS selector finds all unchecked and disabled checkboxes? Those links provide answers to how to find unchecked or disabled checkboxes, respectively, and this question shows how to find an element with one pseudo-class and one pseudo-element, but I'm looking to find multiple pseudo classes on the same element.

I think the answer is to chain them without spaces (i.e., input[type="checkbox"]:disabled:not(:checked), and this seems to work, but I don't know how to tell if this is working correctly or doing something else and returning what I want by coincidence.

Daniel Kaplan
  • 62,768
  • 50
  • 234
  • 356

3 Answers3

1

You can combine psuedo-classes by putting them next to each other without whitespace. Note that the * isn't strictly needed here, but maybe helps show intent:

*:not(:checked):disabled {
  outline: 3px solid red;
}
<input type="checkbox" /> <br>
<input type="checkbox" disabled/> <br>
<input type="checkbox" checked/> <br>
<input type="checkbox" checked disabled/>
romellem
  • 5,792
  • 1
  • 32
  • 64
1

'this seems to work' - no it doesn't as it picks up those checkboxes that are checked. Put a :not in and you'll be OK.

input[type="checkbox"]:disabled:not(:checked)

Here's a snippet showing the various combinations. cyan is what your code would select and pink is the one you actually want.

input[type="checkbox"]:disabled:checked+label {
  background: cyan;
}

input[type="checkbox"]:disabled:not(:checked)+label {
  background: pink;
}
<input type="radio" checked><label>Radio checked</label>
<input type="radio"><label>Radio unchecked not disabled</label>
<input type="checkbox"><label>Checkbox not checked not disabled</label>
<input type="checkbox" disabled><label>Checkbox not checked disabled</label>
<input type="checkbox" checked><label>Checkbox checked not disabled</label>
<input type="checkbox" checked disabled><label>Checkbox checked disabled</label>
A Haworth
  • 30,908
  • 4
  • 11
  • 14
0

As :checked and :disabled are element attributes you can alternatively use their attribute selector form instead of the pseudo selectors, but that would make your CSS a little less transparent.

UPDATE

As @Kaiido correctly commented, this solution did not account for checkboxes inside a <fieldset disabled>, making it not work properly. I adjusted the code to work with and without a parent <fieldset> either disabled or not. The accepted answer, however, does not work correctly (for now).

input[type="checkbox"]:is(:not(:checked):disabled,
                          :not(:checked)[disabled],
                          :not([checked]):disabled,
                          :not([checked])[disabled]) {
  outline: 3px solid green;
}
<p>no fieldset</p>
<input type="checkbox"> <label>unchecked</label><br>
<input type="checkbox" disabled> <label>unchecked disabled</label><br>
<input type="checkbox" checked> <label>checked</label><br>
<input type="checkbox" checked disabled> <label>checked disabled</label><br>
<br>

<fieldset>
  <legend>fieldset</legend>
  <input type="checkbox"> <label>unchecked</label><br>
  <input type="checkbox" disabled> <label>unchecked disabled</label><br>
  <input type="checkbox" checked> <label>checked</label><br>
  <input type="checkbox" checked disabled> <label>checked disabled</label>
</fieldset>
<br>
<fieldset disabled>
  <legend>fieldset disabled</legend>
  <input type="checkbox"> <label>unchecked</label><br>
  <input type="checkbox" disabled> <label>unchecked disabled</label><br>
  <input type="checkbox" checked> <label>checked</label><br>
  <input type="checkbox" checked disabled> <label>checked disabled</label>
</fieldset>
Rene van der Lende
  • 4,992
  • 2
  • 14
  • 25
  • Only the `disabled` attribute is reflected, you can't assume that `:not([checked])` equals `:not(:checked)`, and actually you can't even assume it for `disabled`, since `:disabled` can be inherited from `
    ` even for an `` that would match `:not([disabled])`.
    – Kaiido Nov 08 '22 at 02:18
  • @Kaiido, you're right, I checked inside `
    `. Unfortunately, this is also true for the accepted answer. Updated the answer to catch all options.
    – Rene van der Lende Nov 08 '22 at 14:41