An interesting approach used by Ionic Foundation to style the input track of a range using only CSS. They add the ::before pseudo-element to ::-webkit-slider-thumb , making it as wide as possible, and then positioning it on top of the track. (I could not get border-radius to work with it.)
input[type='range'] { width: 210px; height: 30px; overflow: hidden; cursor: pointer; } input[type='range'], input[type='range']::-webkit-slider-runnable-track, input[type='range']::-webkit-slider-thumb { -webkit-appearance: none; } input[type='range']::-webkit-slider-runnable-track { width: 200px; height: 10px; background: #AAA; } input[type='range']::-webkit-slider-thumb { position: relative; height: 30px; width: 30px; margin-top: -10px; background: steelblue; border-radius: 50%; border: 2px solid white; } input[type='range']::-webkit-slider-thumb::before { position: absolute; content: ''; height: 10px; width: 500px; left: -502px; top: 8px; background: #777; }
<div class="container"> <input type="range" min="0" max="100" value="10" /> </div>
As far as I know, there is no pure CSS way for this for browsers that support Webkit (and FF) . IE provides a way to smooth out two parts of a track using -ms-fill-lower and -ms-fill-upper , but there are no equivalents in WebKit, and therefore JavaScript is required.
You can use linear-gradient as the background image for the executable track, and then change the background-size using JavaScript to achieve the desired effect. Since the question is specific to Webkit, the snippet provided currently only works in browsers running Webkit . This method allows us to add border-radius to the track.
This snippet was adapted from Ana Tudor CodePen Demo . This demo has ways to make it work in other browsers.
window.onload = function() { var input = document.querySelector('input[type=range]'), style_el = document.createElement('style'), styles = [], track_sel = ['::-webkit-slider-runnable-track']; document.body.appendChild(style_el); styles.push(''); input.addEventListener('input', function() { var min = this.min || 0, max = this.max || 100, c_style, u, edge_w, val, str = ''; this.setAttribute('value', this.value); val = this.value + '% 100%'; str += 'input[type="range"]' + track_sel[0] + '{background-size:' + val + '}'; styles[0] = str; style_el.textContent = styles.join(''); }, false); }
input[type='range'] { width: 210px; height: 50px; cursor: pointer; } input[type='range'], input[type='range']::-webkit-slider-runnable-track, input[type='range']::-webkit-slider-thumb { -webkit-appearance: none; } input[type='range']::-webkit-slider-runnable-track { width: 200px; height: 10px; background: linear-gradient(to right, #777, #777), #AAA; background-size: 10% 100%; background-repeat: no-repeat; border-radius: 5px; } input[type='range']::-webkit-slider-thumb { height: 30px; width: 30px; margin-top: -10px; background: steelblue; border-radius: 50%; border: 2px solid white; }
<div class="container"> <input type="range" min="0" max="100" value="10" /> </div>
source share