1

I am using a checkbox as a way to modify the other element's style. Is it possible for a checkbox to affect other classes/elements of the website.

I have a sample html code below, instead of changing label element, is it possible to change the styling of the first div instead.

ul li {
  display: inline-block;
}

ul li input[type="checkbox"]:checked+label {
  border: 2px solid gray;
  background-color: gray;
  color: #fff;
  transition: all .2s;
}

ul li {
  padding: 20px;
  margin: 20px;
}

ul li input[type="checkbox"] {
  display: absolute;
}

ul li input[type="checkbox"] {
  position: absolute;
  opacity: 0;
}

ul li label {
  padding: 20px;
  cursor: pointer;
}
<div class="modify-box">
  BOX TO CHANGED
</div>
<ul>
  <li>
    <input type="checkbox" id="vehicle1" name="vehicle1" value="Bike">
    <label for="vehicle1"> Bike</label><br>
  </li>
  <li>
    <input type="checkbox" id="vehicle2" name="vehicle2" value="Car">
    <label for="vehicle2"> Car</label><br>
  </li>
  <li>
    <input type="checkbox" id="vehicle3" name="vehicle3" value="Boat">
    <label for="vehicle3"> Boat</label><br>
  </li>
</ul>
biberman
  • 5,606
  • 4
  • 11
  • 35
IyanAndru
  • 13
  • 1
  • 3
  • If you want first parent div then css hasn't parent selector – fatm Oct 14 '21 at 10:05
  • you need to use Javascript also – Aman Sharma Oct 14 '21 at 10:17
  • No, that is not possible. Current CSS allows only to select downwards and to the right in the DOM structure, not upwards or to the left. See also: [Is there a CSS parent selector?](https://stackoverflow.com/q/1014861/1427878) – CBroe Oct 14 '21 at 10:34
  • But if you can modify the HTML structure, then you could put the actual checkbox inputs _before_ the div element - they are visually hidden anyway, the labels can stay where they are. _Then_ you could select the div element based on the checkbox's status. – CBroe Oct 14 '21 at 10:37

3 Answers3

1

There is a way to make this happen, but it's to use exactly the same "trick" with which you style the <label> elements, specifically by moving the <input> elements ahead of the element you wish to style.

With that in mind, if the <input> elements are preceding siblings of the <div>, then checking, and unchecking, the <input> can have an effect on the <div>, and also the original <label> elements as well.

As a crude example:

input[type="checkbox"][name^="vehicle"] {
  display: absolute;
  position: absolute;
  opacity: 0;
}

/* styles the <div> based on the checked/unchecked state
   of the <input> (this example assumes that the same
   highlight colour should be used regardless of which
   <input> is checked: */
input[type="checkbox"][name^="vehicle"]:checked ~ div {
  background-color: #ccc;
}

/* this is where it becomes obvious that JavaScript (or,
   ideally, a CSS selector that can refer to an attribute-
   variable) makes more sense; though with a CSS
   pre-processor this can be written effectively enough.
   Here when the #vehicle1 element is checked the <label>
   descendents with a "for" attribute equal to "vehicle1" of
   later-sibling <ul> elements are selected and styled: */
#vehicle1:checked~ul label[for=vehicle1] {
  background-color: gray;
}

/* as above, for the "vehicle2" id and for attributes: */
#vehicle2:checked~ul label[for=vehicle2] {
  background-color: gray;
}

#vehicle3:checked~ul label[for=vehicle3] {
  background-color: gray;
}

ul li {
  display: inline-block;
  padding: 20px;
  margin: 20px;
}

ul li label {
  padding: 20px;
  cursor: pointer;
}
<input type="checkbox" id="vehicle1" name="vehicle1" value="Bike">
<input type="checkbox" id="vehicle2" name="vehicle2" value="Car">
<input type="checkbox" id="vehicle3" name="vehicle3" value="Boat">
<div class="modify-box">
  BOX TO CHANGED
</div>
<ul>
  <li>
    <label for="vehicle1"> Bike</label><br>
  </li>
  <li>
    <label for="vehicle2"> Car</label><br>
  </li>
  <li>
    <label for="vehicle3"> Boat</label><br>
  </li>
</ul>
David Thomas
  • 249,100
  • 51
  • 377
  • 410
0

With only CSS this won't be possible. You are restricted by the current selectors and there are no parent selectors in CSS. You can use a bit of JS to target the element you want.

What would you like to happen in the box surrounding the checkboxes? Maybe there would be another solution with a :before or :after on the label?

Dorien
  • 13
  • 4
0

I think you need JavaScript for that. You could listen for the change event and style if no checkbox is checked.


First you need to select the containing list element and attach an event listener to it:

document.querySelector('ul').addEventListener('change', function(e) {...});

In the handler function of the listener you have to check if there is a checked checkbox and depending on that check style your .modify.box (or toggle a class, for example .checked):

if (document.querySelector('input:checked')) {
  modify_box.classList.add('checked');
}
else {
  modify_box.classList.remove('checked');
}

If you decide to toggle a class you need to add that class to your CSS-definition. For example:

ul li input[type="checkbox"]:checked+label,
.checked {...}

Working example:

const modify_box = document.querySelector('.modify-box');

document.querySelector('ul').addEventListener('change', function(e) {
  if (document.querySelector('input:checked')) {
    modify_box.classList.add('checked');
  }
  else {
    modify_box.classList.remove('checked');
  }
});
ul li {
  display: inline-block;
}

ul li input[type="checkbox"]:checked+label,
.checked {
  border: 2px solid gray;
  background-color: gray;
  color: #fff;
  transition: all .2s;
}

ul li {
  padding: 20px;
  margin: 20px;
}

ul li input[type="checkbox"] {
  display: absolute;
}

ul li input[type="checkbox"] {
  position: absolute;
  opacity: 0;
}

ul li label {
  padding: 20px;
  cursor: pointer;
}
<div class="modify-box">
  BOX TO CHANGED
</div>
<ul>
  <li>
    <input type="checkbox" id="vehicle1" name="vehicle1" value="Bike">
    <label for="vehicle1"> Bike</label><br>
  </li>
  <li>
    <input type="checkbox" id="vehicle2" name="vehicle2" value="Car">
    <label for="vehicle2"> Car</label><br>
  </li>
  <li>
    <input type="checkbox" id="vehicle3" name="vehicle3" value="Boat">
    <label for="vehicle3"> Boat</label><br>
  </li>
</ul>
biberman
  • 5,606
  • 4
  • 11
  • 35