How to style HTML5 range input to have different color before and after slider?

enter image description here

I want the left side to be green and the right side to be gray. As pictured above would be PERFECT. Preferably a pure CSS solution (only need to worry about WebKit).

Is such a thing possible?


Solution 1:

Pure CSS solution:

  • Chrome: Hide the overflow from input[range], and fill all the space left to thumb with shadow color.
  • IE: no need to reinvent the wheel: ::-ms-fill-lower
  • Firefox no need to reinvent the wheel: ::-moz-range-progress

/*Chrome*/
@media screen and (-webkit-min-device-pixel-ratio:0) {
    input[type='range'] {
      overflow: hidden;
      width: 80px;
      -webkit-appearance: none;
      background-color: #9a905d;
    }
    
    input[type='range']::-webkit-slider-runnable-track {
      height: 10px;
      -webkit-appearance: none;
      color: #13bba4;
      margin-top: -1px;
    }
    
    input[type='range']::-webkit-slider-thumb {
      width: 10px;
      -webkit-appearance: none;
      height: 10px;
      cursor: ew-resize;
      background: #434343;
      box-shadow: -80px 0 0 80px #43e5f7;
    }

}
/** FF*/
input[type="range"]::-moz-range-progress {
  background-color: #43e5f7; 
}
input[type="range"]::-moz-range-track {  
  background-color: #9a905d;
}
/* IE*/
input[type="range"]::-ms-fill-lower {
  background-color: #43e5f7; 
}
input[type="range"]::-ms-fill-upper {  
  background-color: #9a905d;
}
<input type="range"/>

Solution 2:

While the accepted answer is good in theory, it ignores the fact that the thumb then cannot be bigger than size of the track without being chopped off by the overflow: hidden. See this example of how to handle this with just a tiny bit of JS.

// .chrome styling Vanilla JS

document.getElementById("myinput").oninput = function() {
  var value = (this.value-this.min)/(this.max-this.min)*100
  this.style.background = 'linear-gradient(to right, #82CFD0 0%, #82CFD0 ' + value + '%, #fff ' + value + '%, white 100%)'
};
#myinput {
  background: linear-gradient(to right, #82CFD0 0%, #82CFD0 50%, #fff 50%, #fff 100%);
  border: solid 1px #82CFD0;
  border-radius: 8px;
  height: 7px;
  width: 356px;
  outline: none;
  transition: background 450ms ease-in;
  -webkit-appearance: none;
}
<div class="chrome">
  <input id="myinput" min="0" max="60" type="range" value="30" />
</div>

Solution 3:

Yes, it is possible. Though I wouldn't recommend it because input range is not really supported properly by all browsers because is an new element added in HTML5 and HTML5 is only a draft (and will be for long) so going as far as to styling it is perhaps not the best choice.

Also, you'll need a bit of JavaScript too. I took the liberty of using jQuery library for this, for simplicity purposes.

Here you go: http://jsfiddle.net/JnrvG/1/.