2

It's simple to apply CSS to checked/unchecked checkboxes (using :checked) and their labels. However, I need to apply another style to all checkboxes when all of them are unchecked.

This is relatively simple to implement using JavaScript but I have a widget which I'm not eager to modify so I'd like to know whether there's a CSS trick for that. I suspect that there isn't, but there's always somebody who's smarter :)

PS well, the html bit looks like this, nothing special:

<div>
    <input type=checkbox id=chkFilterMath>
      <span><label for=chkFilterMath>Math</label></span>
    <input type=checkbox id=chkFilterHist>
      <span><label for=chkFilterHist>History</label></span>
    ...
</div>

Current CSS uses the

input:not(:checked) + span label

selector to apply the styles to unchecked checkboxes/labels.

A simplified example may be found here: https://jsfiddle.net/k56hz8va/ I'd like to set color: black to the labels when all of checkboxes are unchecked.

YakovL
  • 7,557
  • 12
  • 62
  • 102
  • @DavidThomas I've added html and css above; sufficient styles would be just greying out labels (`color:grey`) of all unckecked checkboxes unless all of them are unchecked – YakovL Dec 18 '17 at 13:35

3 Answers3

2

Lasciate ogni speranza, voi ch’entrate

No. There are no such CSS selectors that allows to select previous DOM elements in dependence on state of following elements. See Is there a “previous sibling” CSS selector? and Is there a CSS parent selector? posts for details.

Alexander
  • 4,420
  • 7
  • 27
  • 42
1

There is a hack around this that I use: Hide the input itself, but keep the label. Then use the pseudo element ::before to insert some icon to denote checked / unchecked.

Here's a demo: https://codepen.io/anon/pen/WdrdPE

and the code:

<input id="option_1" type="checkbox"><label for="option_1">thing 1</label>
<input id="option_2" type="checkbox"><label for="option_2">thing 2</label>
<input id="option_3" type="checkbox"><label for="option_3">thing 3</label>

css:

@import url('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css');

input {
  display:none;
}
label {
  display:block;
}
input:checked + label {
  color:red; 
}

label:before {
  content:"\f1db";
  margin-right:.3em;
  font-family:Fontawesome;
}

input:checked + label:before {
  content:"\f058";
  margin-right:.3em;
  font-family:Fontawesome;
}
sashaikevich
  • 167
  • 13
  • I'm afraid, you missed the point: I know how to set styles to checked/unchecked checkboxes and their labels, I'm asking if it's possible to set certain styles when *all* of them are unchecked – YakovL Dec 18 '17 at 13:38
  • You're right - I addressed something totally different. For what you have in mind I'd turn to JS – sashaikevich Dec 18 '17 at 13:49
1

The @sashaikevich's idea is great but requires some work to solve your question. You could place the labels after all inputs. Then your CSS and HTML will be bulky, but you will be able to control styles of the labels in dependence on all inputs state.
Try to run the snippet below. The latest rule has highest priority, therefore if any (at least one) of checkboxes is checked, then the labels is black. Otherwise the labels is red.

[type=checkbox] {
  display: none;
}

#check-box-1:checked~[for=check-box-1] .glyphicon-unchecked,
#check-box-2:checked~[for=check-box-2] .glyphicon-unchecked,
#check-box-3:checked~[for=check-box-3] .glyphicon-unchecked,
#check-box-1:not(:checked)~[for=check-box-1] .glyphicon-check,
#check-box-2:not(:checked)~[for=check-box-2] .glyphicon-check,
#check-box-3:not(:checked)~[for=check-box-3] .glyphicon-check
{
  display: none;
}

[for] {
  color: red;
}

[type=checkbox]:checked~[for] {
  color: inherit;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="check-box-set">
  <input id="check-box-1" type="checkbox" />
  <input id="check-box-2" type="checkbox" checked="checked" />
  <input id="check-box-3" type="checkbox" />
  <label for="check-box-1">
    <span class="glyphicon glyphicon-unchecked" aira-hidden="true"></span>
    <span class="glyphicon glyphicon-check" aira-hidden="true"></span>
    1
  </label>
  <label for="check-box-2">
    <span class="glyphicon glyphicon-unchecked" aira-hidden="true"></span>
    <span class="glyphicon glyphicon-check" aira-hidden="true"></span>
    2
  </label>
  <label for="check-box-3">
    <span class="glyphicon glyphicon-unchecked" aira-hidden="true"></span>
    <span class="glyphicon glyphicon-check" aira-hidden="true"></span>
    3
  </label>
</div>

In the example I use Bootstrap Glyphicons. But it is possible to use another glyps, images or CSS shapes.

Alexander
  • 4,420
  • 7
  • 27
  • 42
  • aha! That's what I was expecting, some really smart trick. I'll think about this and reselect this as accepted if I can adapt it to my needs (or comment why I can't otherwise) – YakovL Dec 18 '17 at 20:51
  • Ok, @YakovL. While my previous answer is accepted, I can't delete one. – Alexander Dec 20 '17 at 13:04