AlexG AlexG - 1 month ago 8
HTML Question

Setting a [CSS] :hover and :checked condition

I have a :hover effect applied --

td img.off{
display:none;
}

td:hover img.off{
display:inline;
}

td:hover img.on{
display:none;
}


-- on some images.

<td>
<div class="col1"><img class="on" src="1.bmp"></div>
<div class="col1"><img class="off" src="2.bmp"></div>
</td>


I'm trying to add a checkbox that disables the hover effect if it's active, so I tried to do --

input:checked + td:hover img.off{
display:inline;
}

input:checked + td:hover img.on{
display:none;
}


-- with this checkbox:

<input type="checkbox" name="box" class="cbox">


But it didn't work. I'm looking for a HTML/CSS solution to this. Anyone know why it's not working?

EDIT: What's wrong here?



input {
display: none;
}
label[for="chkbox1"] {
display: inline-block;
border: 1px solid black;
width: 20px;
height: 20px;
}
input:checked + .header label:after {
content: 'X';
}
table td img.off{
display:none;
}
input:checked + table td:hover img.off{
display:inline;
}
input:checked + table td:hover img.on{
display:none;
}

<input id="chkbox1" type="checkbox" name="box" class="cbox">

<div class="header">
<label for="chkbox1"></label>
</div>

<table>
<tr>
<td>
<div class="col1">
<img class="on" src="http://placehold.it/50">
</div>
<div class="col1">
<img class="off" src="http://placehold.it/100">
</div>
</td>
</tr>
</table>




Answer

Based on your posted code I assume the below markup.

The sibling selector + target a sibling and in below case it will be the table, not the td

input:checked + table td:hover img.on {
  border: 2px solid red;
}
<input type="checkbox" name="box" class="cbox">
<table>
  <tr>
    <td>
      <div class="col1">
        <img class="on" src="http://placehold.it/50">
      </div>
    </td>
  </tr>
</table>

If you want the checkbox to be in the header, you'll need to do a trick using a label, like this

input {
  display: none;
}
label[for="chkbox1"] {
  display: inline-block;
  border: 1px solid black;
  width: 20px;
  height: 20px;
}
input:checked ~ table td:hover img.on {
  border: 2px solid red;
}
input:checked + .header label:after {
  content: 'X';
}
<input id="chkbox1" type="checkbox" name="box" class="cbox">

<div class="header">
  <label for="chkbox1"></label>
</div>

<table>
  <tr>
    <td>
      <div class="col1">
        <img class="on" src="http://placehold.it/50">
      </div>
    </td>
  </tr>
</table>

To clarify what will NOT work, below sample, as the actual checkbox is a child of the header and can't reach the img using the sibling selector.

For this to work a parent selector would be needed and those does not exist (yet)

input:checked ~ table td:hover img.on {
  border: 2px solid red;
}
<div class="header">
  <input id="chkbox1" type="checkbox" name="box" class="cbox">
</div>

<table>
  <tr>
    <td>
      <div class="col1">
        <img class="on" src="http://placehold.it/50">
      </div>
    </td>
  </tr>
</table>

Update after question edit

You need to use the ~ sibling selector, not the immediate sibling selector +, as the table does not come as an immediate sibling of the input

input {
  display: none;
}
label[for="chkbox1"] {
  display: inline-block;
  border: 1px solid black;
  width: 20px;
  height: 20px;
}
input:checked + .header label:after {
  content: 'X';
}
table td img.off {
  display:none;
}
input:checked ~ table td:hover img.off {
  display:inline;
}
input:checked ~ table td:hover img.on {
  display:none;
}
<input id="chkbox1" type="checkbox" name="box" class="cbox">

<div class="header">
  <label for="chkbox1"></label>
</div>

<table>
  <tr>
    <td>
      <div class="col1">
        <img class="on" src="http://placehold.it/50/0f0">
      </div>
      <div class="col1">
        <img class="off" src="http://placehold.it/100/0ff">
      </div>
    </td>
  </tr>
</table>

Comments