skip to Main Content

I am working on a switch checkbox input and currently the style changes when I click on the switch knob only. But, I cannot figure out how to make the switch style change when the switch input is checked and slider is clicked instead of the knob itself.

<input type="checkbox" id="toggle"/>
<div>
  <label for="toggle"></label>
</div>
input[type="checkbox"] {
  display: none;
}
/* style switch when 'unchecked' */
div {
  position: relative;
  width: 42px;
  height: 26px;
  background: #cccccc;
  border-radius: 20px;
}
/* style switch knob */
label {
  position: absolute;
  width: 22px;
  height: 22px;
  background: #ffffff;
  top: 2px;
  left: 2px;  
  border-radius: 50%;
  cursor: pointer;
}

/* style slider and knob when switch is 'checked' */
input[type="checkbox"]:checked ~ div label {
  -webkit-transform: translateX(16px);
  -ms-transform: translateX(16px);
  transform: translateX(16px);
}
input[type="checkbox"]:checked ~ div {
  background: #0071d0;
}

/* style knob when switch is unchecked. */
label::before {
  position: absolute;
  content: '1F5D9';
  width: 10px;
  height: 10px;
  left: 3px;
  top: -1px;
}

/* style knob when switch is checked. */
input[type="checkbox"]:checked ~ div label::before {
  position: absolute;
  content: '2713';
  width: 10px;
  height: 10px;
  left: 5px;
}

Can someone take a look and help me with this? Thanks!

Link: https://codepen.io/Zack-Oliver/pen/poqGeYO

3

Answers


  1. Clicking the label element has the same effect as clicking the checkbox. This means that rather than wrapping your label in a div, you need the label to wrap a span instead. The label needs to be the wrapper, if you like.

    input[type="checkbox"] {
      display: none;
    }
    /* style switch when 'unchecked' */
    label {
      display: inline-block;
      position: relative;
      width: 42px;
      height: 26px;
      background: #cccccc;
      border-radius: 20px;
    }
    /* style switch knob */
    label>span {
      position: absolute;
      width: 22px;
      height: 22px;
      background: #ffffff;
      top: 2px;
      left: 2px;  
      border-radius: 50%;
      cursor: pointer;
    }
    
    /* style slider and knob when switch is 'checked' */
    input[type="checkbox"]:checked ~ label>span {
      transform: translateX(16px);
    }
    input[type="checkbox"]:checked ~ label {
      background: #0071d0;
    }
    
    /* style knob when switch is unchecked. */
    label>span::before {
      position: absolute;
      content: 'n';
      width: 100%;
      height: 100%;
      top: -2px;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    /* style knob when switch is checked. */
    input[type="checkbox"]:checked ~ label>span::before {
      content: 'y';
    }
    <input type="checkbox" id="toggle"/>
    <label for="toggle"><span></span></label>

    However, I prefer this simplified version without a glyph inside the switch.

    input[type="checkbox"] {
      display: none;
    }
    
    label {
      display: inline-block;
      position: relative;
      width: 42px;
      height: 26px;
      background: #cccccc;
      border-radius: 20px;
    }
    
    label::before {
      content: '';
      position: absolute;
      width: 22px;
      height: 22px;
      background: #ffffff;
      top: 2px;
      left: 2px;  
      border-radius: 50%;
      cursor: pointer;
    }
    
    input[type="checkbox"]:checked ~ label {
      background: #0071d0;
    }
    
    input[type="checkbox"]:checked ~ label::before {
      transform: translateX(16px);
    }
    <input type="checkbox" id="toggle"/>
    <label for="toggle"></label>
    Login or Signup to reply.
  2. Just playing around with your code gave me this. As said above, the label needs to be the wrapper.

    input[type="checkbox"] {
      display: none;
    }
    
    /* style switch when 'unchecked' */
    div {
      position: relative;
      width: 48px;
      height: 26px;
      background: #cccccc;
      border-radius: 20px;
    }
    
    /* style switch knob */
    label {
      position: absolute;
      width: 100%;
      height: 22px;
      top: 2px;
      left: 2px;  
      border-radius: 50%;
      cursor: pointer;
    }
    
    /* style slider and knob when switch is 'checked' */
    input[type="checkbox"]:checked + label::before {
      transform: translateX(16px);
      background: white;
      border-radius: 50%;
    }
     div:has(input[type="checkbox"]:checked) {
      background: #0071d0;
    }
    
    /* style knob when switch is unchecked. */
    label::before {
      position: absolute;
      content: '1F5D9';
      width: 22px;
      height: 22px;
      left: 5px;
    }
    
    /* style knob when switch is checked. */
    input[type="checkbox"]:checked + label::before {
      position: absolute;
      content: '2713';
      border-radius: 50%;
      background: white;
      text-align: center;
    }
    <div>
      <input type="checkbox" id="toggle"/>
      <label for="toggle"></label>
    </div>

    Brett’s is a nicer answer, though.

    Login or Signup to reply.
  3. To change the switch style when the switch input is checked and the slider is clicked instead of the knob itself, you can modify your HTML and CSS as follows:

    /* Add styles for when the input is checked */
    .switch-input:checked + .slider {
      background-color: #2196F3;
    }
    
    /* Add styles for when the slider is clicked */
    .switch:hover .slider {
      background-color: #64B5F6;
    }
    <label class="switch">
      <input type="checkbox" class="switch-input">
      <span class="slider"></span>
    </label>

    Add this in your code and try to run.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search