1

body{
  padding: 0;
  margin: 0;
  height: 100%;
}
.switch{
  width: fit-content;
    height: fit-content;

    position: absolute;
    top:0;
    bottom: 0;
    left: -50px;
    right: 0;

    margin: auto;
}
.track{
  z-index: -1;
  position: absolute;
  top: 2px;
  left: 1px;
  background-color: #353b48;
  height: 20px;
  width: 48px;
  border-radius: 14px;
}
.circle{
  z-index: 0;
  position: absolute;
  height: 25px;
  width: 25px;
  background-color: #dcdde1;
  border-radius: 50%;
  pointer-events: none;
  transition: .1s;
}
.checkbox{
  position: absolute;
  height: 25px;
  width: 50px;
  padding: 0;
  margin: 0;
  transition: .1s;
  opacity: 0;
}
.checkbox:checked ~ .circle{
  transform: translateX(100%);
}
.background_overlay{
  position: absolute;
  width: 100%;
  height: 100vh;
  background-color: red;
  z-index: -2;
  transition: .1s;
}
.checkbox:checked ~ .background_overlay{
  background-color: green;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="style.css">
    <title></title>
  </head>
  <body>
    <div class="switch">
      <input type="checkbox" name="" value="" class="checkbox">
      <div class="circle"></div>
      <div class="track"></div>
    </div>
    <div class="background_overlay"></div>
  </body>
</html>

So I wanna change the color of the div called "background_overlay" when checkbox is :active. The thing is, the background_overlay div is out of the switch div which contains the checkbox. I looked on internet but I can't figure out how to do this, there is no selector for this case. How could I achieve this please?

  • 2
    This is not possible with HTML and CSS. It is possible with javascript. – user1601324 Sep 14 '20 at 19:02
  • @user1601324 This IS possible, cf. my answer ... – Bazaim Sep 14 '20 at 19:23
  • @Bazaim only because you change the HTML. Lots of things are possible if you change the question :) In the text the questioner directly says "the background_overlay div is out of the switch div which contains the checkbox" and they are correct where they say "there is no selector for this case". It is not possible to select a parent's sibling element in CSS. – user1601324 Sep 14 '20 at 19:27

2 Answers2

1

This is possible, you where not far away from a solution.

What i've done :

  • change <div class="switch"> into <label for="bg-switch" class="switch">
  • add id="bg-switch" to the checkbox
  • change .checkbox:checked ~ .circle{ to .checkbox:checked ~ .switch .circle{

body{
  padding: 0;
  margin: 0;
  height: 100%;
}
.switch{
  width: fit-content;
    height: fit-content;

    position: absolute;
    top:0;
    bottom: 0;
    left: -50px;
    right: 0;

    margin: auto;
}
.track{
  z-index: -1;
  position: absolute;
  top: 2px;
  left: 1px;
  background-color: #353b48;
  height: 20px;
  width: 48px;
  border-radius: 14px;
}
.circle{
  z-index: 0;
  position: absolute;
  height: 25px;
  width: 25px;
  background-color: #dcdde1;
  border-radius: 50%;
  pointer-events: none;
  transition: .1s;
}
.checkbox{
  position: absolute;
  height: 25px;
  width: 50px;
  padding: 0;
  margin: 0;
  transition: .1s;
  opacity: 0;
}
.checkbox:checked ~ .switch .circle{
  transform: translateX(100%);
}
.background_overlay{
  position: absolute;
  width: 100%;
  height: 100vh;
  background-color: red;
  z-index: -2;
  transition: .1s;
}
.checkbox:checked ~ .background_overlay{
  background-color: green;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="style.css">
    <title></title>
  </head>
  <body>
    <input type="checkbox" name="" value="" class="checkbox" id="bg-switch">
    <checkbox="bg-switch" class="switch">
      <div class="circle"></div>
      <div class="track"></div>
    </label>
    <div class="background_overlay"></div>
  </body>
</html>

Edit: It working by using the CSS operator ~ and adding for on the <label>.

Bazaim
  • 2,216
  • 1
  • 7
  • 20
0

I changed your code a bit, but it seems to be working fine now.

I basically put everything in one div, and centered all the elements in the middle with a bit of fine tuning

Doing it with JavaScript would have made it much easier as you have more control over the DOM

body {
    padding: 0;
    margin: 0;
    height: 100%;
}

.switch {
    margin: auto;
}

.track {
    z-index: -1;
    position: absolute;
    top: 2px;
    left: 1px;
    background-color: #353b48;
    height: 20px;
    width: 48px;
    border-radius: 14px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.circle {
    z-index: 0;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-95%, -50%);
    height: 25px;
    width: 25px;
    background-color: #dcdde1;
    border-radius: 50%;
    pointer-events: none;
    transition: .1s;
}

.checkbox {
    position: absolute;
    height: 25px;
    width: 50px;
    padding: 0;
    margin: 0;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    transition: .1s;
    opacity: 0;
}

.checkbox:checked~.circle {
    transform: translateY(-50%);
}

.background_overlay {
    position: absolute;
    width: 100%;
    height: 100vh;
    background-color: red;
    z-index: -2;
    transition: .1s;
}

input[type="checkbox"]:checked+#d2 {
    background-color: green !important;
}

And the HTML

<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
    <meta charset="utf-8">
    <title></title>
</head>

<body>

    <div class="switch">
        <input type="checkbox" name="" value="" id="d1" class="checkbox" />
        <div class="background_overlay" id="d2"></div>
        <div class="circle"></div>
        <div class="track"> </div>
    </div>

</body>

</html>