- let opts = ['Yes, please', 'No, thanks'];
- let n = opts.length;
- let k = 0;

style
  - for(let i = 0; i < n; i++)
    | .wrap > :nth-of-type(#{i + 1}) { --i: #{i} }
.wrap(role='group' aria-label='toggle' style=`--k: ${k}`)
  - for(let i = 0; i < n; i++)
    input(type='radio' name='o' id=`o${i}` checked=i === k)
    label(for=`o${i}`) #{opts[i]}
View Compiled
$w: 8em;
$h: 2em;
$d: .75*$h;
$r: .5*$d;
$o: .5*($h - $d);
$x: $w - $h;
$g: #fefefe, #7e7e7e;
$t: 1s;

* { margin: 0; font: inherit }

body, div, label { display: grid }

body {
  margin: 0;
  min-height: 100vh;
  background: #3c3c3c;
  color: #fff
}

.wrap {
  place-self: center;
  width: $w; height: $h;
  border-radius: $h;
  font: 2.5em ubuntu, sans-serif;
  
  > *, &::after { grid-area: 1/ 1 }
  
  > * {
    --not-sel: min(1, max(var(--k) - var(--i), var(--i) - var(--k)));
    --sel: calc(1 - var(--not-sel))
  }
  
  &::after {
    box-sizing: border-box;
    place-self: center start;
    z-index: 1;
    margin: $o;
    padding: .05em;
    width: $d; height: $d;
    border-radius: 50%;
    transform: translate(calc(var(--k)*#{$x}));
    background: 
      repeating-conic-gradient(from 9deg, $g 5%, $g, nth($g, 1) 50%) content-box, 
      linear-gradient(gainsboro, dimgray) border-box;
    transition: transform $t;
    content: ''
  }
}

input {
  z-index: calc(2 + var(--not-sel));
  width: $w; height: $h;
  opacity: 0;
  cursor: pointer
}

label {
  --not-i: calc(1 - var(--i));
  --sgn-i: calc(2*var(--i) - 1);
  --hue: calc(75 - var(--i)*65);
  place-content: center;
  border-radius: inherit;
  box-shadow: 
    inset 0 .125em .125em #212121, 
    inset 0 .125em .25em hsl(var(--hue), 80%, 40%), 
    inset 0 -.125em .125em rgba(#929292, .65);
  background: 
    linear-gradient(
        hsl(var(--hue), 65%, 45%), hsl(var(--hue), 65%, 65%));
  text-indent: calc(var(--sgn-i)*var(--sel)*-1em);
  clip-path: 
    inset(0 calc(var(--i)*var(--not-sel)*100%) 
          0 calc(var(--not-i)*var(--not-sel)*100%));
  transition: clip-path $t, text-indent $t
}
View Compiled
/* this is ALL the JS that's needed */
addEventListener('change', e => {
  let _t = e.target;
  
  _t.parentNode.style.setProperty('--k', +_t.id.substring(1))
})
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.