Is it possible to style ::before of a checked checkbox's label?

14,578

Unfortunately, in CSS, there is no preceding-sibling (or parent) selector; therefore we're unable to style the <label> based on the state (:checked or otherwise) of its subsequent <input> sibling. The posted CSS:

.remember input[type=checkbox]:checked + label::before{
    content: '';
    background-color: #7b519d;
}

Will work only if the <input> element precedes the <label>:

<div class="remember">
  <input type="checkbox" id="remember-me">
  <label for="remember-me" class="block">Remember Me</label>
</div>

/* Setting the defaults for the unchecked state: */
.remember input[type=checkbox] + label::before {
  content: '';
  display: inline-block;
  width: 1em;
  height: 1em;
}

.remember input[type=checkbox]:checked + label::before {
  content: '';
  background-color: #7b519d;
}
<div class="remember">
  <input type="checkbox" id="remember-me">
  <label for="remember-me" class="block">Remember Me</label>
</div>

Although you can use float to visually move the <label> before the <input>:

.remember input[type=checkbox] + label {
  float: left;
}

.remember input[type=checkbox] + label {
  float: left;
}

.remember input[type=checkbox] + label::before {
  content: '';
  display: inline-block;
  width: 1em;
  height: 1em;
}

.remember input[type=checkbox]:checked + label::before {
  content: '';
  background-color: #7b519d;
}
<div class="remember">
  <input type="checkbox" id="remember-me">
  <label for="remember-me" class="block">Remember Me</label>
</div>

Or, depending on your cross-browser requirements, you could instead use flex-box and take advantage of the order property (and the various vendor-prefixed implementations) to position the elements correctly (order: 1 for the <label> and order: 2 for the <input>):

.remember {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-box-direction: normal;
  -moz-box-direction: normal;
  -webkit-box-orient: horizontal;
  -moz-box-orient: horizontal;
  -webkit-flex-direction: row;
  -ms-flex-direction: row;
  flex-direction: row;
  -webkit-flex-wrap: nowrap;
  -ms-flex-wrap: nowrap;
  flex-wrap: nowrap;
  -webkit-box-pack: start;
  -moz-box-pack: start;
  -webkit-justify-content: flex-start;
  -ms-flex-pack: start;
  justify-content: flex-start;
  -webkit-align-content: stretch;
  -ms-flex-line-pack: stretch;
  align-content: stretch;
  -webkit-box-align: start;
  -moz-box-align: start;
  -webkit-align-items: flex-start;
  -ms-flex-align: start;
  align-items: flex-start;
}
.remember input:nth-child(1) {
  -webkit-box-ordinal-group: 3;
  -moz-box-ordinal-group: 3;
  -webkit-order: 2;
  -ms-flex-order: 2;
  order: 2;
  -webkit-box-flex: 0;
  -moz-box-flex: 0;
  -webkit-flex: 0 1 auto;
  -ms-flex: 0 1 auto;
  flex: 0 1 auto;
  -webkit-align-self: auto;
  -ms-flex-item-align: auto;
  align-self: auto;
}
.remember label:nth-child(2) {
  -webkit-box-ordinal-group: 2;
  -moz-box-ordinal-group: 2;
  -webkit-order: 1;
  -ms-flex-order: 1;
  order: 1;
  -webkit-box-flex: 0;
  -moz-box-flex: 0;
  -webkit-flex: 0 1 auto;
  -ms-flex: 0 1 auto;
  flex: 0 1 auto;
  -webkit-align-self: auto;
  -ms-flex-item-align: auto;
  align-self: auto;
}
.remember input[type=checkbox] + label::before {
  content: '';
  display: inline-block;
  width: 1em;
  height: 1em;
}
.remember input[type=checkbox]:checked + label::before {
  content: '';
  background-color: #7b519d;
}
<div class="remember">
  <input type="checkbox" id="remember-me">
  <label for="remember-me" class="block">Remember Me</label>
</div>

(Note that the above CSS for the flexbox demo was taken more or less in whole from the the-echoplex.net's "Flexy Boxes" playground.)

References:

Share:
14,578
Aras
Author by

Aras

Updated on June 05, 2022

Comments

  • Aras
    Aras almost 2 years

    I'm trying to style a css injected ::before element of a label after the checkbox is selected. Is it possible? If it is how do I do it?

    I have a checkbox and a label:

    <div class="remember">
        <label for="remember-me" class="block">Remember Me</label>
        <input type="checkbox" id="remember-me">
    </div>
    

    I'm trying to do something like this with css:

    .remember input[type=checkbox]:checked + label::before{
        content: '';
        background-color: #7b519d;
    }
    

    I made a fiddle