@import "compass/css3";

$track-u: 1em;
$track-k: 6;
$track-min: 1;
$track-max: 4;
$track-w: ($track-max - $track-min + 1)*$track-k*$track-u;
$track-h: 1em;
$track-sh: 0 1px 1px #fff, 
  inset 0 1px 1px #1b4662;
$track-bg: 
  repeating-linear-gradient(135deg, 
      #427998, #427998 1px, #3a7293 1px, #3a7293 .375em)
  #3a7293;
$track-fill: 
  repeating-linear-gradient(135deg, 
      #7db547, #7db547 1px, #6ca436 1px, #6ca436 .375em);

$ruler-c: #417a9b;
$ruler-txt-n: #3f7999;
$ruler-txt-hl: #ffffb6;
$ruler-bg-n: #c8d9e4;
$ruler-bg-hl: #61a027;
$ruler-line-w: .125em;
$ruler-line-major-h: $track-h;
$ruler-line-minor-h: $track-h/4;
$ruler-txt: VPS-1G VPS-2G VPS-4G VPS-6G;
$ruler-txt-fs: .75;

$bubble-s: 4;
$bubble-w: $bubble-s*$track-u;
$bubble-h: 1em;
$bubble-bg: 
  radial-gradient(circle at 100% 50%, 
      $ruler-bg-n $track-h/2/$ruler-txt-fs, 
      transparent $track-h/2/$ruler-txt-fs) 
    ($track-k*$track-u - $bubble-w + $bubble-h)/2/$ruler-txt-fs 0, 
  radial-gradient(circle at 0 50%, 
      $ruler-bg-n $track-h/2/$ruler-txt-fs, 
      transparent $track-h/2/$ruler-txt-fs) 
    ($track-k*$track-u + $bubble-w - $bubble-h)/2/$ruler-txt-fs 0, 
  linear-gradient(90deg, 
      $ruler-bg-n ($bubble-w - $bubble-h)/$ruler-txt-fs, 
      transparent ($bubble-w - $bubble-h)/$ruler-txt-fs) 
    ($track-k*$track-u - $bubble-w + $bubble-h)/2/$ruler-txt-fs 0;
$bubble-bg-hl: 
  radial-gradient(circle at 100% 50%, 
      $ruler-bg-hl $track-h/2/$ruler-txt-fs, 
      transparent $track-h/2/$ruler-txt-fs) no-repeat
    (-$track-k*$track-u - $bubble-w + $bubble-h)/2/$ruler-txt-fs 0, 
  radial-gradient(circle at 0 50%, 
      $ruler-bg-hl $track-h/2/$ruler-txt-fs, 
      transparent $track-h/2/$ruler-txt-fs) no-repeat
    ($track-k*$track-u + $bubble-w - $bubble-h)/2/$ruler-txt-fs 0, 
  linear-gradient(90deg, 
      $ruler-bg-hl ($bubble-w - $bubble-h)/$ruler-txt-fs, 
      transparent ($bubble-w - $bubble-h)/$ruler-txt-fs) no-repeat
    ($track-k*$track-u - $bubble-w + $bubble-h)/2/$ruler-txt-fs 0;
$bubble-bp: 100%/($track-max - $track-min + 1);

$input-h: 3*$track-h;

$thumb-bc: #2b404e;
$thumb-w: $track-k*$track-u;
$thumb-h: 2em;
$thumb-bg: 
  repeating-linear-gradient(90deg, 
      #e9e9e9, #e9e9e9 1px, transparent 1px, transparent 2px) no-repeat 50% 50%, 
  linear-gradient(#4e6b7c, #1e3b4d);
$thumb-cp: ();
$thumb-n: 30;
$thumb-ba: 360deg/$thumb-n;
$thumb-ro: $thumb-h/4;
$thumb-ri: $thumb-ro/3;
$thumb-d: 3*$thumb-ri/2;

@for $i from 0 through $thumb-n {
  $theta: $i*$thumb-ba;
  $x: $thumb-w/2 + 
    ($thumb-ro + $thumb-ri)*cos($theta + 90deg) - 
    $thumb-d*cos(($thumb-ro + $thumb-ri)*$theta/$thumb-ri + 90deg);
  $y: $thumb-h/2 + 
    ($thumb-ro + $thumb-ri)*sin($theta + 90deg) - 
    $thumb-d*sin(($thumb-ro + $thumb-ri)*$theta/$thumb-ri + 90deg);
  
  $thumb-cp: $thumb-cp, $x $y;
}

@mixin track($flag: false) {
  width: $track-w; height: $track-h;
  border-radius: $track-h;
  box-shadow: $track-sh;
  background: $track-bg;
  
  @if $flag {
    .js & {
      background: $track-fill no-repeat, $track-bg;
      background-size: $track-k*$track-u/2 100%, 100% 100%;
    }
  }
}

@mixin fill() {
  border-radius: $track-h/2;
  box-shadow: $track-sh;
  background: $track-fill;
}

@mixin thumb($flag: true) {
  width: $thumb-w; height: $thumb-h;
  
  @if $flag {
    box-sizing: border-box;
    border: solid 1px $thumb-bc;
    border-radius: .25em;
    background: $thumb-bg;
    background-size: .3125em .5em, 100% 100%;
  }
}

html { background: #e1ecf4; }

input[type='range'] {
  &, 
  &::-webkit-slider-runnable-track, 
  &::-webkit-slider-thumb {
    -webkit-appearance: none;
  }
  
  position: absolute;
  top: 50%; left: 50%;
  border: solid 0 transparent;
  border-width: 2*$bubble-h $track-h 0;
  padding: 0;
  width: $track-w; height: $input-h;
  border-radius: .5em;
  transform: translate(-50%, -50%);
  background: 
    linear-gradient(90deg, 
        $ruler-c, $ruler-c $ruler-line-w, 
        transparent $ruler-line-w, transparent $track-k*$track-u) 
      repeat-x 
      ($track-k*$track-u - $ruler-line-w)/2 
      ($input-h - $track-h)/2 - $ruler-line-major-h 
      content-box, 
    linear-gradient(90deg, 
        $ruler-c, $ruler-c $ruler-line-w, 
        transparent $ruler-line-w, transparent $track-u) 
      repeat-x 
      $track-u - $ruler-line-w/2  
      ($input-h - $track-h)/2 - $ruler-line-minor-h 
      content-box;
  background-size: 
    $track-k*$track-u $ruler-line-major-h, 
    $track-u $ruler-line-minor-h;
  font-size: 1em;
  cursor: pointer;
  
  &::-webkit-slider-runnable-track {
    position: relative;
    @include track(true);
  }
  &::-moz-range-track {
    @include track();
  }
  &::-ms-track {
    border: none;
    @include track();
    color: transparent;
  }
  
  &::-moz-range-progress {
    height: $track-h;
    @include fill();
  }
  &::-ms-fill-lower {
    @include fill();
  }
  
  &::-webkit-slider-thumb {
    position: relative;
    margin-top: ($track-h - $thumb-h)/2;
    @include thumb(false);
    filter: drop-shadow(0 0 1px darken($thumb-bc, 20%));
  }
  &::-moz-range-thumb {
    @include thumb();
  }
  &::-ms-thumb {
    @include thumb();
  }
  
  &::-ms-tooltip { display: none; }
  
  &::-webkit-slider-runnable-track, /deep/ #track {
    &:before, &:after {
      position: absolute;
      bottom: 235%;
      width: $track-w/$ruler-txt-fs;
      height: $bubble-h/$ruler-txt-fs;
      font: 700 #{$ruler-txt-fs*1em} / #{1.05*$bubble-h/$ruler-txt-fs} 
        arial, sans-serif;
      text-indent: ($track-k*$track-u - $bubble-w)/2/$ruler-txt-fs + .875em;
    }
    &:before {
      background: $bubble-bg;
      background-size: $track-k*$track-u/$ruler-txt-fs 100%;
      filter: drop-shadow(0 1px #fff) 
        drop-shadow(0 -1px #1b4662);
      color: $ruler-txt-hl;
      content: '';
      
      .js & {
        background: $bubble-bg-hl, $bubble-bg;
        background-size: $track-k*$track-u/$ruler-txt-fs 100%;
        content: '#{nth($ruler-txt, 1)}';
      }
    }
    &:after {
      color: $ruler-txt-n;
      word-spacing: $track-k*$track-u/$ruler-txt-fs - 3.9375em;
      content: '#{$ruler-txt}';
      
      .js & {
        clip-path: polygon(0 0, 0 100%, 100% 100%, 100% 0, 0 0, 
          0 0, 100%/($track-max - $track-min + 1) 0, 
          100%/($track-max - $track-min + 1) 100%, 0 100%, 0 0);
      }
    }
  }
  
  &::-webkit-slider-thumb, /deep/ #thumb {
    &:before {
      position: absolute;
      top: 0; left: 0;
      @include thumb();
      clip-path: polygon($thumb-cp);
      content: '';
    }
  }
  
  @for $i from $track-min through $track-max {
    $t1: (2*$i - 1)*$track-k*$track-u;
    $p1: ((2*$i - 3)*$track-k*$track-u - $bubble-w + $bubble-h)/2/$ruler-txt-fs;
    $p2: ($t1 + $bubble-w - $bubble-h)/2/$ruler-txt-fs;
    $p3: ($t1 - $bubble-w + $bubble-h)/2/$ruler-txt-fs;
    
    .js &[value='#{$i}'] {
      &::-webkit-slider-runnable-track {
        background-size: (.5 + $i - $track-min)*$track-k*$track-u 100%, 100% 100%;
      }
      
      &::-webkit-slider-runnable-track, /deep/ #track {
        &:before {
          background-position: 
            $p1 0, $p2 0, $p3 0, $p3 0, $p2 0, $p3 0;
          text-indent: ($t1 - $bubble-w)/2/$ruler-txt-fs + .875em;
          content: '#{nth($ruler-txt, $i)}';
        }
        &:after {
          clip-path: polygon(0 0, 0 100%, 100% 100%, 100% 0, 0 0, 
            ($i - $track-min)*$bubble-bp 0, 
            ($i - $track-min + 1)*$bubble-bp 0, 
            ($i - $track-min + 1)*$bubble-bp 100%, 
            ($i - $track-min)*$bubble-bp 100%, 
            ($i - $track-min)*$bubble-bp 0);
        }
      }
    }
  }
  
  &:focus {
    outline: none;
    box-shadow: 0 0 .125em #97a6b0;
  }
}
View Compiled
var range_el = document.querySelector('input[type=range]');

range_el.addEventListener('input', function() {
  this.setAttribute('value', this.value);
}, false);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.