- let min = -50, max = 50;
- let thumbs = [
- { val: -15, lbl: 'Value A' },
- { val: 20, lbl: 'Value B' },
- { val: -35, lbl: 'Value C' },
- { val: 45, lbl: 'Value D' }
- ];
- let nv = thumbs.length;
- let layers = thumbs.map((c, i) => `linear-gradient(90deg, red calc(var(--r) + (var(--v${i}) - var(--min))/var(--dif)*var(--uw)), transparent 0)`);
.wrap(role='group' aria-labelledby='multi-lbl'
style=`${thumbs.map((c, i) => `--v${i}: ${c.val}`).join('; ')};
--min: ${min}; --max: ${max};
--fill: ${layers.join(', ')}`)
#multi-lbl Multi thumb slider:
- for(let i = 0; i < nv; i++)
label.sr-only(for=`v${i}`) #{thumbs[i].lbl}
input(type='range' id=`v${i}` min=min value=thumbs[i].val max=max)
output(for=`v${i}` style=`--c: var(--v${i})`)
View Compiled
$pad: 2em;
$hlc: #f90;
$t: .3s;
@mixin track() {
width: 100%; height: 100%;
background: none /* get rid of Firefox track background */
}
@mixin thumb() {
box-sizing: border-box; /* different between Chrome & Firefox */
/* box-sizing needed now that we have a non-zero border */
border: solid calc(.5*var(--r)) transparent;
width: var(--d); height: var(--d);
border-radius: 50%; /* make circular */
background:
linear-gradient(rgba(#000, .15), rgba(#fff, .2)) content-box,
linear-gradient(rgba(#fff, .3), rgba(#000, .3)) border-box,
$hlc;
pointer-events: auto
}
* {
--hl: 0;
--nothl: calc(1 - var(--hl));
margin: 0;
font: inherit
}
body {
display: grid;
place-content: center;
overflow-x: hidden;
min-height: 100vh;
background:
repeating-linear-gradient(45deg, #ddd, #ddd 5px, transparent 0, transparent 7px) #eee
}
.wrap {
--w: 20em;
--h: 1.75em;
--d: var(--h);
--r: calc(.5*var(--d));
--uw: calc(var(--w) - var(--d));
--dif: calc(var(--max) - var(--min));
display: grid;
grid-template-rows: max-content var(--h) max-content;
grid-gap: .625em;
overflow: hidden;
position: relative;
margin: 1em .5em - $pad;
padding: 0 $pad;
width: var(--w);
font: 700 1.125em ubuntu mono, consolas, monaco, monospace;
&::before, &::after {
grid-column: 1;
grid-row: 2;
border-radius: var(--r);
box-shadow: inset 0 2px 3px rgba(#000, .3);
background: #ccc;
color: #eee;
content: ''
}
&::after {
filter: Grayscale(var(--nothl));
/* non-standard WebKit version */
-webkit-mask: var(--fill);
-webkit-mask-composite: xor;
/* standard version, supported in Firefox */
mask: var(--fill);
mask-composite: exclude;
background:
linear-gradient(rgba(#fff, .3), rgba(#000, .3))
#95a;
transition: filter $t ease-out
}
&:focus-within { --hl: 1 }
}
.sr-only {
position: absolute;
clip-path: inset(50%)
}
input[type='range'] {
&::-webkit-slider-runnable-track,
&::-webkit-slider-thumb, & {
-webkit-appearance: none
}
grid-column: 1;
grid-row: 2;
z-index: calc(1 + var(--hl));
top: 0; left: 0;
background: none; /* get rid of white Chrome background */
filter: grayScale(var(--nothl));
transition: filter $t ease-out;
cursor: grab;
pointer-events: none;
&::-webkit-slider-runnable-track { @include track }
&::-moz-range-track { @include track }
&::-webkit-slider-thumb { @include thumb }
&::-moz-range-thumb { @include thumb }
&:focus {
outline: solid 0 transparent;
&, & + output { --hl: 1 }
}
&:active { cursor: grabbing }
}
output {
grid-column: 1;
grid-row: 3;
margin-left: var(--r);
max-width: max-content;
transform: translate(calc((var(--c) - var(--min))/var(--dif)*var(--uw)));
&::after {
display: block;
border-radius: 5px;
padding: 0 .375em;
transform: translate(-50%) scale(var(--hl));
background:
linear-gradient(rgba(#fff, .3), rgba(#000, .3))
$hlc;
color: #fff;
transition: transform $t ease-out;
counter-reset: c var(--c);
content: counter(c)
}
}
View Compiled
addEventListener('input', e => {
let _t = e.target;
_t.parentNode.style.setProperty(`--${_t.id}`, +_t.value)
}, false);
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.