- 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 tpos = thumbs.map((c, i) => `calc(var(--r) + (var(--v${i}) - var(--min))/var(--dif)*var(--uw))`);
- let fill = tpos.map(c => `linear-gradient(90deg, red ${c}, transparent 0)`);
- let hole = tpos.map(c => `radial-gradient(circle at ${c}, red var(--r), transparent 0)`)

.wrap(role='group' aria-labelledby='multi-lbl' 
      style=`${thumbs.map((c, i) => `--v${i}: ${c.val}`).join('; ')}; 
             --min: ${min}; --max: ${max};
             --fill: ${fill.join(', ')}; 
             --hole: ${hole.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 */
  transform: scale(calc(1 - .5*var(--nothl)));
  background: $hlc;
  transition: transform $t ease-out;
  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: url(https://images.unsplash.com/photo-1571388571275-971dc17e5ac8?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ) 50%/ cover #d7d7d7;
  background-blend-mode: overlay;
}

.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;
    align-self: center;
    height: 6px;
    border-radius: var(--r);
    background: 
      repeating-linear-gradient(-45deg, 
          grey, grey 3px, transparent 0, transparent 7px) #fff;
    color: #eee;
    --mask: linear-gradient(red, red), var(--hole);
    /* non-standard WebKit version */
    -webkit-mask: var(--mask);
    -webkit-mask-composite: xor;
    /* standard version, supported in Firefox */
            mask: var(--mask);
            mask-composite: exclude;
    content: ''
  }
  
  &::after {
    background: #95a;
    filter: Grayscale(var(--nothl));
    --mask: var(--fill);
    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: $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

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.