<label for="toggle">
  <button type="button" id="toggle" role="switch" aria-checked="false">
    <span class="slider"></span>
  </button>
</label>

<script>
  const button = document.querySelector('#toggle');

button.addEventListener('click', (e) => {  
  let el = e.target;
  let state = el.getAttribute('aria-checked');
  let isState = (state === 'true');
  
  el.setAttribute('aria-checked', isState ? false : true)
});
</script>

:root {
  --switch-width: 3.6rem;
  --switch-height: 2rem;
  --slider-size: .5rem;
  --switch-transform-width: 1.8rem;
  --switch-color-on: #2196F3;
  --switch-color-off: #ccc ;
}

[role="switch"] {  
  padding: 0;
  width: var(--switch-width);
  height: var(--switch-height);
  position:relative;
  border: 0;
  border-radius: 1rem;
  background-color: var(--switch-color-off);
  
}

[role="switch"][aria-checked="true"] {
  background-color: var(--switch-color-on);
}

[role="switch"] span {
  color: var(--switch-color-off);
  padding: var(--slider-size);  
  pointer-events: none;
  border-radius: 1rem;
  postion: absolute;
  left: 3px;
  top: 4px;
}

[role="switch"][aria-checked="false"] span {
  -webkit-transform: translateX(var(--switch-transform-width));
  -ms-transform: translateX(var(--switch-transform-width));
  transform: translateX(var(--switch-transform-width));
  color: var(--switch-color-off);
}

.slider {
  position: absolute;
  cursor: pointer;
  inset: 0;
  background-color: white;
  -webkit-transition: .4s;
  transition: .4s;
  width: var(--slider-size);
  height: var(--slider-size);
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.