<div class='wrap'>
  <input id='r' type='range'/>
</div>
$bg: #3d3d4a;
$fsr: 4;
$p: 39%;
$k: .1;
$t: .5s;
$track-w: 25em;
$track-h: .02*$track-w;
$thumb-d: $k*$track-w;

$chart-d: (1 - 2*$k)*100%;

@mixin track() {
  border: none;
  width: $track-w; height: $track-h;
  border-radius: .5*$track-h;
  background: #343440
}

@mixin thumb() {
  border: none;
  width: $thumb-d; height: $thumb-d;
  border-radius: 50%;
  transform: scale(.7);
  background: #e6323e;
  filter: saturate(.7);
  transition: transform $t linear, filter $t
}

@mixin thumb-focus() {
  transform: none;
  filter: none
}

%thumb-val {
  position: absolute;
  width: $thumb-d; height: $thumb-d;
  opacity: 0;
  color: #fff;
  pointer-events: none;
  transition: opacity $t ease-in-out
}

* { margin: 0 }

body { background: $bg }

.wrap {
  margin: 2em auto;
  width: $track-w;
  font: 2vmin trebuchet ms, arial, sans-serif;
  
  @media (max-width: 500px), 
         (max-height: 500px) { font-size: 10px }
  @media (min-width: 1600px), 
         (min-height: 1600px) { font-size: 32px }
  
  &:not(.full) {
    position: relative;
    
    output {
      @extend %thumb-val;
      top: 0;
      transform: translate(calc(var(--val)/100*#{$track-w - $thumb-d}))
    }
  }
  
  &.full {
    position: relative;
    height: $track-w;
    
    [type='range'] {
      display: block;
      transform-origin: 100% 0;
      transform: rotate(-90deg) translatey(-100%);
    }
    
    output {
      width: $chart-d; height: $chart-d;
      border-radius: 50%;
      color: #7a7a7a;
      font-size: $fsr*1em;
      font-weight: 700;
      
      &:before {
        @extend %thumb-val;
        right: 0; bottom: 0;
        transform: translatey(calc(var(--val)/-100*#{$track-w - $thumb-d}));
        line-height: $thumb-d;
        text-align: center;
        font-size: 1em/$fsr;
        font-weight: 200;
        counter-reset: val var(--val);
        content: counter(val)'%'
      }
    }
  }
}

[type='range'] {
  &, &::-webkit-slider-thumb { -webkit-appearance: none }

  padding: 0;
  width: $track-w; height: $thumb-d;
  background: transparent;
  font: inherit;
  cursor: pointer;

  &::-webkit-slider-runnable-track { @include track }
  &::-moz-range-track { @include track }
  &::-ms-track { @include track }

  &::-webkit-slider-thumb {
    margin-top: .5*($track-h - $thumb-d);
    @include thumb
  }
  &::-moz-range-thumb { @include thumb }
  &::-ms-thumb {
    margin-top: 0;
    @include thumb
  }
  
  &::-ms-tooltip { display: none }
  
  + output {
    display: flex;
    align-items: center;
    justify-content: center;
    background: radial-gradient($bg $p, transparent $p + .5%),
      conic-gradient(#e64c65 calc(var(--val)*1%), #41a8ab 0%);
    
    &:after { content: '%' }
  }
  
  &:focus {
    outline: none;
    
    &::-webkit-slider-thumb { @include thumb-focus }
    &::-moz-range-thumb { @include thumb-focus }
    &::-ms-thumb { @include thumb-focus }
    
    .wrap:not(.full) & + output, 
    .wrap.full & + output:before { opacity: 1 }
  }
}
View Compiled
const _R = document.getElementById('r'), 
      _W = _R.parentNode, 
      _O = document.createElement('output');

let val = null, conic = false;

function update() {
  let newval = +_R.value;

  if(val !== newval) {
    _W.style.setProperty('--val', _O.value = val = newval);
    if(conic) _O.setAttribute('aria-label', `${val}%`)
  }
};

update();

_O.setAttribute('for', _R.id);
_W.appendChild(_O);

if(getComputedStyle(_O).backgroundImage !== 'none') {
  conic = true;
  _W.classList.add('full');
  _O.setAttribute('role', 'img');
  _O.setAttribute('aria-label', `${val}%`)
}

addEventListener('input', update, false);
addEventListener('change', update, false);
View Compiled

External CSS

  1. https://codepen.io/thebabydino/pen/evPbxv.js

External JavaScript

  1. https://codepen.io/thebabydino/pen/evPbxv.js