1

I recently asked for help in getting my images to replace the checkboxes. I have accomplished that, however when I "check" my boxes, I would like them to either remain at opacity:1 OR replace the image with a new one. (Just testing the opacity idea first.) None of my ideas have worked so far. The below JSFiddle is what I have so far!

JSFiddle

input[type=checkbox].equipment {
  display: none;
}
label {
  display: inline-block;
  padding: 0 0 0 0px;
  -webkit-transition: opacity 0.25s;
  -moz-transition: opacity 0.25s;
  -o-transition: opacity 0.25s;
  transition: opacity 0.25s;
}
.speaker {
  height: 150px;
  width: 150px;
  border-radius: 5px;
  cursor: pointer;
  background: url(http://www.djscimmia.com/new-web/_assets/b615_150px.png);
  opacity: 0.5;
}
.speaker:hover {
  opacity: 1;
}
.subwoofer {
  height: 150px;
  width: 150px;
  border-radius: 5px;
  cursor: pointer;
  background: url(http://www.djscimmia.com/new-web/_assets/b1800hp_150px.png);
  opacity: 0.5;
}
.subwoofer:hover {
  opacity: 1;
}
.smokemachine {
  height: 150px;
  width: 150px;
  border-radius: 5px;
  cursor: pointer;
  background: url(http://www.djscimmia.com/new-web/_assets/smoke_150px.png);
  opacity: 0.5;
}
.smokemachine:hover {
  opacity: 1;
}
input[type=checkbox] + label.speaker {
  background: url(http://www.djscimmia.com/new-web/_assets/b615_150px.png) no-repeat;
  cursor: pointer;
  opacity: 0.5;
}
input[type=checkbox] + label.subwoofer {
  background: url(http://www.djscimmia.com/new-web/_assets/b1800hp_150px.png) no-repeat;
  cursor: pointer;
  opacity: 0.5;
}
input[type=checkbox] + label.smokemachine {
  background: url(http://www.djscimmia.com/new-web/_assets/smoke_150px.png) no-repeat;
  cursor: pointer;
  opacity: 0.5;
}
input[type=checkbox]:checked + label {
  opacity: 1;
}
<label class="equipment-lab speaker" for="speaker">
  <input type="checkbox" name="equipment" value="speaker" id="speaker" class="equipment">
</label>
<label class="equipment-lab subwoofer" for="subwoofer">
  <input type="checkbox" name="equipment" value="subwoofer" id="subwooder" class="equipment">
</label>
<label class="equipment-lab smokemachine" for="smoke-machine">
  <input type="checkbox" name="equipment" value="smoke-machine" id="smoke-machine" class="equipment">
</label>
Harry
  • 87,580
  • 25
  • 202
  • 214
Anake.me
  • 467
  • 1
  • 6
  • 20
  • 1
    You need it to be like [this](https://jsfiddle.net/9qjj7012/3/)? – Harry Mar 05 '16 at 12:04
  • That IS one way, however would you also know the way to REPLACE the image when checked with another? – Anake.me Mar 05 '16 at 12:05
  • Ok, refer to my answer. In it, all the images change to speaker image with full opacity when the checkbox is checked. – Harry Mar 05 '16 at 12:08

2 Answers2

2

As per your current markup the label is the parent of the input and not a sibling but the selector that you are using is a sibling selector (+) and hence it doesn't select or change the opacity of the label. In CSS, we cannot select and style the parent element based on it's children's state and hence your markup needs to be changed.

Once the markup is changed, we can select and style the label by using the below selector:

input[type=checkbox]:checked + label {
  background: url(http://www.djscimmia.com/new-web/_assets/b615_150px.png);
  opacity: 1;
}

The above selector selects the label which is the adjacent (immediate next) sibling of the check box which is checked and change its opacity and background-image.

input[type=checkbox].equipment {
  display: none;
}
label {
  display: inline-block;
  padding: 0 0 0 0px;
  -webkit-transition: opacity 0.25s;
  -moz-transition: opacity 0.25s;
  -o-transition: opacity 0.25s;
  transition: opacity 0.25s;
}
.equipment-lab {
  height: 150px;
  width: 150px;
  border-radius: 5px;
}
input[type=checkbox]:checked + label {
  background: url(http://www.djscimmia.com/new-web/_assets/b615_150px.png);
  opacity: 1;
}
.speaker {
  background: url(http://www.djscimmia.com/new-web/_assets/b615_150px.png);
  opacity: 0.5;
  cursor: pointer;
}
.subwoofer {
  background: url(http://www.djscimmia.com/new-web/_assets/b1800hp_150px.png);
  opacity: 0.5;
  cursor: pointer;
}
.smokemachine {
  background: url(http://www.djscimmia.com/new-web/_assets/smoke_150px.png);
  opacity: 0.5;
  cursor: pointer;
}
<input type="checkbox" name="equipment" value="speaker" id="speaker" class="equipment">
<label class="equipment-lab speaker" for="speaker">
</label>
<input type="checkbox" name="equipment" value="subwoofer" id="subwoofer" class="equipment">
<label class="equipment-lab subwoofer" for="subwoofer">
</label>
<input type="checkbox" name="equipment" value="smoke-machine" id="smoke-machine" class="equipment">
<label class="equipment-lab smokemachine" for="smoke-machine">
</label>

If you want the images for each of them to be different then you can write multiple selectors like below and add the appropriate background setting to it.

#speaker:checked + label.speaker {
  background: url(http://www.djscimmia.com/new-web/_assets/b1800hp_150px.png);
  opacity: 1;
}
#subwoofer:checked + label.subwoofer {
  background: url(http://www.djscimmia.com/new-web/_assets/smoke_150px.png);
  opacity: 1;
}
#smoke-machine:checked + label.smokemachine {
  background: url(http://www.djscimmia.com/new-web/_assets/b615_150px.png);
  opacity: 1;
}

input[type=checkbox].equipment {
  display: none;
}
label {
  display: inline-block;
  padding: 0 0 0 0px;
  -webkit-transition: opacity 0.25s;
  -moz-transition: opacity 0.25s;
  -o-transition: opacity 0.25s;
  transition: opacity 0.25s;
}
.equipment-lab {
  height: 150px;
  width: 150px;
  border-radius: 5px;
}
#speaker:checked + label.speaker {
  background: url(http://www.djscimmia.com/new-web/_assets/b1800hp_150px.png);
  opacity: 1;
}
#subwoofer:checked + label.subwoofer {
  background: url(http://www.djscimmia.com/new-web/_assets/smoke_150px.png);
  opacity: 1;
}
#smoke-machine:checked + label.smokemachine {
  background: url(http://www.djscimmia.com/new-web/_assets/b615_150px.png);
  opacity: 1;
}
.speaker {
  background: url(http://www.djscimmia.com/new-web/_assets/b615_150px.png);
  opacity: 0.5;
  cursor: pointer;
}
.subwoofer {
  background: url(http://www.djscimmia.com/new-web/_assets/b1800hp_150px.png);
  opacity: 0.5;
  cursor: pointer;
}
.smokemachine {
  background: url(http://www.djscimmia.com/new-web/_assets/smoke_150px.png);
  opacity: 0.5;
  cursor: pointer;
}
<input type="checkbox" name="equipment" value="speaker" id="speaker" class="equipment">
<label class="equipment-lab speaker" for="speaker">
</label>
<input type="checkbox" name="equipment" value="subwoofer" id="subwoofer" class="equipment">
<label class="equipment-lab subwoofer" for="subwoofer">
</label>
<input type="checkbox" name="equipment" value="smoke-machine" id="smoke-machine" class="equipment">
<label class="equipment-lab smokemachine" for="smoke-machine">
</label>

For creating a gradual transition between the checked and unchecked states, just add a transition setting to the label (this is already there in your snippet but doesn't have much of a visual effect as the duration is very small).

label {
  display: inline-block;
  padding: 0 0 0 0px;
  -webkit-transition: opacity 0.25s;
  -moz-transition: opacity 0.25s;
  -o-transition: opacity 0.25s;
  transition: opacity 0.25s;
}

One thing to note is that only opacity change can be transitioned and the background change will be instantaneous because background is not a transitionable property as per specs. That said you can still use the sprites concept to animate the background-position and thus produce a gradual change effect. A sample is available here.

(Disclaimer: The image used in that demo is not mine, it was picked from here).

Note: Just in case you have the same misunderstanding as Gene R in comments, I am just showing how to replace images. The images used are just samples and can be replaced with any required image URL.

Community
  • 1
  • 1
Harry
  • 87,580
  • 25
  • 202
  • 214
  • remove `background` from `input[type=checkbox]:checked + label`. It's enough just to play with opacity – Gene R Mar 05 '16 at 12:14
  • @GeneR: Why should it be removed? If you remove it will change only the opacity and not the image. OP (refer comments under question) wants to change `background` also:) – Harry Mar 05 '16 at 12:15
  • OP replaces with exactly same image – Gene R Mar 05 '16 at 12:17
  • *That IS one way, however would you also know the way to REPLACE the image when checked with another?* - This is what OP stated @GeneR. Refer to the last bit of that comment. – Harry Mar 05 '16 at 12:18
  • Well, ok, but your both snippets still replace with wrong images :) – Gene R Mar 05 '16 at 12:20
  • @GeneR: I am just showing a sample of *how to replace images*. I guess there is enough for OP to understand. – Harry Mar 05 '16 at 12:21
  • 1
    Thank you Harry! You have answered my question perfectly!! Would you also know how to create a transition between "checked" and "unchecked"?? – Anake.me Mar 05 '16 at 12:24
  • Also, thank you for going in-depth with your reply! I didnt realise the way my HTML code was set out was wrong. Glad to know what that "+" sign means now! :D – Anake.me Mar 05 '16 at 12:25
  • @Jesse: Transition can be added for `opacity` change but not for `background-image` change. This is because `opacity` change can be linearly interpolated while image cannot be. I will add a snippet of that also to answer. Please consider marking it as accepted if it helped :) (*Edit:* In fact you already have transition for `opacity` so there is nothing much to change). – Harry Mar 05 '16 at 12:25
  • @Harry: I see. Hmm, may have to look for a jQuery or Javascript way around it :/ Thanks! I will mark it as answered :) – Anake.me Mar 05 '16 at 12:28
  • @Jesse: [This](https://jsfiddle.net/9qjj7012/4/) kind of background transition can be done between checked and unchecked states using CSS. This is achieved using a sprite image and `background-position` change. – Harry Mar 05 '16 at 12:50
2

A couple things were getting in your way, mainly your selectors were trying to detect a :checked status of label, not input[type=checkbox], and you needed some jQuery to make sure your boxed were being checked.

$('input.equipment').click(function(){
 ($(this)[0].hasAttribute("checked")) ? $(this).removeAttr("checked"):$(this).attr("checked","checked");
 $(this).closest('label').toggleClass('opaque');
});
input[type=checkbox].equipment {
    display: none;
}

label {
    display: inline-block;
    padding: 0 0 0 0px;
    -webkit-transition: opacity 0.25s;
    -moz-transition: opacity 0.25s;
    -o-transition: opacity 0.25s;
    transition: opacity 0.25s;
}

.equipment-lab{
    height: 150px;
    width: 150px;
    border-radius: 5px;
}

.speaker {
    background: url(http://www.djscimmia.com/new-web/_assets/b615_150px.png);
    opacity: 0.5;
    cursor: pointer;
}

.subwoofer {
    background: url(http://www.djscimmia.com/new-web/_assets/b1800hp_150px.png);
    opacity: 0.5;
    cursor: pointer;
}

.smokemachine {
    background: url(http://www.djscimmia.com/new-web/_assets/smoke_150px.png);
    opacity: 0.5;
    cursor: pointer;
}

.opaque {
    opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<label class="equipment-lab speaker" for="speaker">
    <input type="checkbox" name="equipment" value="speaker" id="speaker" class="equipment">
</label>
<label class="equipment-lab subwoofer" for="subwoofer">
    <input type="checkbox" name="equipment" value="subwoofer" id="subwoofer" class="equipment">
</label>
<label class="equipment-lab smokemachine" for="smoke-machine">
    <input type="checkbox" name="equipment" value="smoke-machine" id="smoke-machine" class="equipment">
</label>
symlink
  • 11,984
  • 7
  • 29
  • 50
  • Thanks Symlink! The answer has already been awarded to Harry though, so I apologise for that, however I see you used jQuery in your answer. Interesting way around it :) Would you happen to know a jQuery or Javascript way to animate the transition between "checked" and "unchecked"? :) – Anake.me Mar 05 '16 at 12:35