Styling input range for webkit with pure CSS

时光总嘲笑我的痴心妄想 提交于 2019-11-28 23:51:15

Interesting approach being used by the Ionic framework for styling the range input track with just CSS. They are adding a ::before pseudo-element to the ::-webkit-slider-thumb, making it as wide as possible and then positioning it on top of the track. (I couldn't 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; /* equal to height of runnable track */
  width: 500px; /* make this bigger than the widest range input element */
  left: -502px; /* this should be -2px - width */
  top: 8px; /* don't change this */
  background: #777;
}
<div class="container">
  <input type="range" min="0" max="100" value="10" />
</div>

As far as I am aware there is no pure CSS way to do this for Webkit powered browsers (and FF). IE provides a way to style the two portions of the track using -ms-fill-lower and -ms-fill-upper but there are no equivalents in WebKit and hence JavaScript will be needed.

You could use a linear-gradient as background image for the runnable track and then change the background-size using JavaScript to achieve the required effect. As question is specific to Webkit, the snippet provided currently works only in Webkit powered browsers. This method does allow us to add a border-radius to the track.

This snippet was adapted from Ana Tudor's CodePen Demo. That demo has ways to make it work in other browsers also.

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>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!