- let states = ['off', 'on'];
- let n = states.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='switch' 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}`) #{states[i]}
View Compiled
@use 'sass:math';
$l: 1.25;
$d: 8em;
$p: 2em;
$b: .125em;
$a: 70deg;
$v: 50deg;
$s: 270deg - .5*$a;
$o: 4*$b;
$u: $d - 2*$o;
$r: .5*$u;
$g: #202020, #696969, #2f2f2f;
$t: .35s;
@property --a {
syntax: '<angle>';
initial-value: 0deg;
inherits: false
}
body, div { display: grid }
body {
margin: 0;
min-height: 100vh;
background: #3c3c3c
}
.wrap {
grid-template: repeat(2, 1em)/ max-content $d + $p + $b;
place-content: space-between end;
place-self: center;
border: solid $b transparent;
padding: $p;
width: $d; height: $d;
border-radius: 50%;
background:
radial-gradient(at calc(50% + .5*#{$b}) calc(50% + #{$b}),
#141414 calc(#{$r} - #{2*$b}),
transparent calc(#{$r} + #{2*$b})),
radial-gradient(closest-side,
nth($g, 3) calc(100% + -1*#{$b} + -1px),
transparent calc(100% + -1*#{$b})) content-box,
conic-gradient(from $s at calc(50% + -1*#{$b/math.sin(.5*$a)}),
nth($g, 3) $a, transparent 0) padding-box,
conic-gradient(from $s,
nth($g, 2), nth($g, 1) $a, transparent 0%) border-box,
linear-gradient(nth($g, 1), nth($g, 2)) content-box;
font: 1em/ 1.25 ubuntu, sans-serif;
> * {
grid-area: calc(1 + var(--i))/ 1;
cursor: pointer
}
&::before, &::after {
--i: 0;
--a: calc((2*var(--k) - 1)*#{$v - $a});
--mask:
conic-gradient(from #{90deg - .5*$v} at 0,
red #{$v}, transparent 0) 0/ 50% no-repeat,
linear-gradient(red, red) content-box;
grid-area: 1/ 2/ span 2;
place-self: center end;
margin: $o - $p;
padding: inherit;
width: $u; height: $u;
border-radius: inherit;
transform:
rotate(var(--a))
scale(calc(1 - var(--i)*#{3*$b/$u}));
background:
linear-gradient(calc(-1*var(--a)),
hsl(0, 0%, calc(9% + var(--i)*12%)),
hsl(0, 0%, calc(41% - var(--i)*12%)));
mask: var(--mask);
mask: var(--mask);
transition: transform $t, --a $t;
content: ''
}
&::after { --i: 1 }
}
input {
z-index: 2;
opacity: 0
}
label {
--hl: 0;
--not-sel: min(1, max(var(--k) - var(--i), var(--i) - var(--k)));
--sel: calc(1 - var(--not-sel));
place-self: center;
padding: .125em .375em;
border-radius: 7px;
box-shadow: 0 0 0 calc(var(--hl)*2px) nth($g, 1);
color:
hsl(calc(10 + var(--i)*60),
calc(var(--sel)*75%),
calc(39% + var(--sel)*20%));
font-size: 1.5em;
transition: color $t;
&:hover, :focus + & { --hl: 1 }
}
View Compiled
addEventListener('change', e => {
let _t = e.target;
_t.parentNode.style.setProperty('--k', +_t.id.substring(1))
})
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.