1

Please note the HTML cannot be modified.

HTML:

<div class="form-group newsletter">
    <div class="checkbox">
        <label><input name="newsletter" type="checkbox" value="Sign me up for exclusive discounts and style advice by email, post and text" aria-invalid="false">Sign me up for exclusive discounts and style advice by email, post and text</label>
    </div>
</div>

SASS:

.form-group {
    input {
        opacity: 0;
    }
    label {
        &:after {
            float: left;
            display: block;
                content: "";
            width: 52px; height: 52px;
                margin-right: 35px;
            background: url('../img/checkbox-default.png') no-repeat;
        }
        input:checked ~ &:after { // This. Not sure how to make this work
            background: url('../img/checkbox-checked.png') no-repeat;
        }
    }
}

https://jsfiddle.net/dfx78wob/

adamj
  • 4,672
  • 5
  • 49
  • 60

4 Answers4

6

This technically will solve your problem...

.form-group label:has(input:checked):after {
    background: url('../img/checkbox-checked.png') no-repeat;
}

... hopefully about 3 years from now.

Jerome Indefenzo
  • 967
  • 6
  • 25
3

There is no sibling element to input tag so using of ~ will not work. You either need to add a sibling element to input tag or add a class to label element. Since, you can't change the HTML the solution is possible only with JavaScript where you have to add a class to label element when input is checked.

input.addEventListener('change', function(){
    var type = this.checked? "add": "remove";
    this.parentElement.classList[type]('checked');
}

And in CSS:

label{
    &.checked::after{  /* instead of "input:checked ~ &:after" */
     /* checked styles here */
    }
}

BTW, it is always a better strategy to keep an empty element adjacent to input tag (because input can't have pseudo elements). So, you won't end up in situations like this :)

Mr_Green
  • 40,727
  • 45
  • 159
  • 271
  • I was leaving that one as a last resort. I thought perhaps someone here might know of a trick or something along those lines to get this going. DAMMIT! haha – adamj Oct 21 '16 at 08:09
0

DEMO:

https://jsfiddle.net/dfx78wob/2/

You have used the ~ operator but label is the parent element in your markup. And there is no parent selector as of now in CSS.

So, I modified the html to make label a sibling of input and modified the style rules to use + instead of ~ as + will select the immediate next element while ~ will select sibling but not necessarily next.

HTML:

<div class="form-group newsletter">
    <div class="checkbox">
        <input name="newsletter" type="checkbox" value="Sign me up for exclusive discounts and style advice by email, post and text" aria-invalid="false" id="checkbox1">
        <label for="checkbox1">Sign me up for exclusive discounts and style advice by email, post and text</label>
    </div>

SCSS:

.form-group {
    input {
        opacity: 0;
    }
    label {
        &:after {
            float: left;
            display: block;
                content: "";
            width: 52px; height: 52px;
                margin-right: 35px;
            background: red;
        }
   }
  input:checked+label:after { // This. Not sure how to make this work
    background: green;
  }
}
Mark Wilson
  • 1,324
  • 2
  • 10
  • 19
  • Hey Mark! Appreciate your help, but the HTML is pre-generated by a plugin I use and I cannot modify it unless I use JS to do it, which isn't something I was gunning to do. If I could modify the HTML I honestly wouldn't be here, because it's a straightforward problem with a straightforward solution – adamj Oct 21 '16 at 08:56
0

No way to do it unless you modify the HTML and this wasn't an option for me, so in the end I used JS as this was the only option for me:

$('<span class="check">').insertAfter( $('.checkbox.newsletter label input') );

Thanks @Sarcoma! Nice shot at the pseudo-element inside input. It just wasn't meant to be (damn you Firefox why have you forsaken me!).

adamj
  • 4,672
  • 5
  • 49
  • 60