- let val = 40;
svg(width='0' height='0')
symbol#vico(viewBox='0 -48 98 96')
g
path(d='M60 22a25 25 0 0 0 0-44')
path(d='M24-11h-19v22h19l20 20v-62z')
path(d='M65 40a43 43 0 0 0 0-80')
div(role='group' aria-label='volume slider' style=`--val: ${val}`)
svg.ico(style='--ico: 0'): use(xlink:href='#vico')
input(type='range' value=val list='l')
svg.ico(style='--ico: 1'): use(xlink:href='#vico')
View Compiled
$s: 1em;
$track-h: .375em;
$track-r: .5*$track-h;
$track-s:
-.25em -.25em .5em #f0f0f0,
.25em .25em .5em #d7d7d7;
$progr-c: hsl(220deg 82% calc(60% - var(--sel)*23%));
$thumb-d: 1.75em;
$thumb-r: .5*$thumb-d;
$rippl-d: $thumb-d + $s;
$rippl-r: .5*$rippl-d;
$rippl-f: $thumb-d/$rippl-d;
$t: .3s;
@mixin track($f: 0) {
width: 100%; height: $track-h;
border-radius: $track-r;
box-shadow: $track-s;
background: tranparent;
@if $f > 0 { /* WebKit only */
background:
linear-gradient(90deg, $progr-c var(--pos), transparent 0);
transition: --sel $t /* Chromium only, no transition in Safari */
}
}
@mixin thumb($o: 0) {
@if $o > 0 { margin-top: $track-r - $thumb-r }
border: none;
width: $thumb-d; height: $thumb-d;
border-radius: 50%;
box-shadow: $track-s;
background: hsl(218deg calc(var(--sel)*76%) calc(90% - var(--sel)*38%));
transition: background $t;
cursor: ew-resize
}
@property --sel {
syntax: '<number>';
initial-value: 0;
inherits: true
}
* {
box-sizing: inherit;
margin: 0;
padding: 0;
font: inherit
}
body, div { display: grid }
body {
box-sizing: border-box;
padding: $s;
min-height: 100vh;
background: #eceef4;
> * {
grid-area: 1/ 1;
place-self: center;
}
}
symbol { color: #4b5565 }
g { fill: currentcolor }
* + [d] {
stroke: currentcolor;
stroke-width: 10;
stroke-linecap: round;
stroke-linejoin: round
}
g + [d] {
fill: none;
opacity: var(--ico)
}
[role='group'] {
--sgn-dir: clamp(-1, var(--val) - var(--prv, var(--val)), 1);
--sel: 0;
--not-sel: calc(1 - var(--sel));
--pos: calc(#{$thumb-r} + .01*var(--val)*(100% - #{$thumb-d}));
grid-gap: $s;
grid-template-columns: max-content 1fr max-content;
padding: 2*$s $s;
width: Min(100%, 32em);
border-radius: 1em;
transform: scale(calc(1 - .05*var(--sel)));
box-shadow:
.5em .5em 1em #d3d8e8,
-.5em -.5em 1em #fefcfe;
background: #e3e5ed;
transition: transform $t;
&::after {
--rippl-s: calc((var(--not-sel)*#{$rippl-f} + var(--sel))*100%);
grid-area: 1/ 2;
position: relative;
left: var(--pos);
margin-left: -$rippl-r;
width: $rippl-d; height: $rippl-d;
border-radius: 50%;
opacity: var(--not-sel);
background:
radial-gradient(closest-side,
transparent $thumb-r, rgba(#286be1, .32) calc(100% - 1px), transparent)
50%/ var(--rippl-s) var(--rippl-s) no-repeat;
--mask:
radial-gradient(transparent #{$thumb-r}, red calc(#{$thumb-r} + 1px));
-webkit-mask: var(--mask);
mask: var(--mask);
transition: calc(var(--sel)*#{$t});
transition-property: background-size, opacity;
transition-delay: 0s, $t;
pointer-events: none;
content: ''
}
&:focus-within { --sel: 1 }
}
[type='range'] {
&::-webkit-slider-runnable-track,
&::-webkit-slider-thumb, & { -webkit-appearance: none }
grid-area: 1/ 2;
background: transparent;
cursor: pointer;
&::-webkit-slider-runnable-track { @include track(1) }
&::-moz-range-track { @include track }
/* pure CSS Firefox-only fill */
&::-moz-range-progress {
height: $track-h;
border-radius: $track-r 0 0 $track-r;
background: $progr-c;
transition: background-color $t
}
&::-webkit-slider-thumb { @include thumb(1) }
&::-moz-range-thumb { @include thumb }
&:focus { outline: none }
}
.ico {
--sgn-ico: calc(2*var(--ico) - 1);
--abs: max(var(--sgn-dir) - var(--sgn-ico), var(--sgn-ico) - var(--sgn-dir));
--hlg: calc(var(--sel)*(1 - min(1, var(--abs))));
align-self: center;
width: $thumb-d; height: $thumb-d;
opacity: calc(1 - .85*(1 - var(--hlg)));
transition: opacity $t
}
View Compiled
addEventListener('input', e => {
let _t = e.target, _p = _t.parentNode;
_p.style.setProperty('--prv', +_p.style.getPropertyValue('--val'))
_p.style.setProperty('--val', +_t.value)
})
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.