So I have recently been playing around with styling the html range slider.
I came across a pen on CodePen that has some really great designs.
This is the source code from one.
HTML:
<input type="range" data-idx="1">
CSS:
html {
  background: #393939;
}
input[type='range'] {
  display: block;
  margin: 2.5em auto;
  border: solid .5em transparent;
  padding: 0;
  width: 15.5em;
  height: 1em;
  border-radius: .25em;
  background: transparent;
  font-size: 1em;
  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: 15.5em;
  height: 0.5em;
  border-radius: 0.25em;
  background: #fff;
}
.js input[type='range']::-webkit-slider-runnable-track {
  background: linear-gradient(#e44e4f, #e44e4f) no-repeat #fff;
}
input[type='range']::-moz-range-track {
  width: 15.5em;
  height: 0.5em;
  border-radius: 0.25em;
  background: #fff;
}
.js input[type='range']::-moz-range-track {
  background: linear-gradient(#e44e4f, #e44e4f) no-repeat #fff;
}
input[type='range']::-ms-track {
  border: none;
  width: 15.5em;
  height: 0.5em;
  border-radius: 0.25em;
  background: #fff;
  color: transparent;
}
input[type='range']::-ms-fill-lower {
  border-radius: 0.25em;
  background: #e44e4f;
}
input[type='range']:nth-of-type(1)::-webkit-slider-runnable-track {
  background-size: 50% 100%;
}
input[type='range']:nth-of-type(1)::-moz-range-track {
  background-size: 50% 100%;
}
input[type='range']:nth-of-type(1)::-webkit-slider-thumb {
  margin-top: -0.125em;
  border: none;
  width: 0.75em;
  height: 0.75em;
  border-radius: 50%;
  box-shadow: 0 0 0.125em #333;
  background: #fff;
}
input[type='range']:nth-of-type(1)::-moz-range-thumb {
  border: none;
  width: 0.75em;
  height: 0.75em;
  border-radius: 50%;
  box-shadow: 0 0 0.125em #333;
  background: #fff;
}
input[type='range']:nth-of-type(1)::-ms-thumb {
  border: none;
  width: 0.75em;
  height: 0.75em;
  border-radius: 50%;
  box-shadow: 0 0 0.125em #333;
  background: #fff;
}
input[type='range']:nth-of-type(1)::-ms-tooltip {
  display: none;
}
input[type='range']:focus {
  outline: none;
  box-shadow: 0 0 0.25em #e44e4f;
}
Javascript:
var s = document.createElement('style'), 
    r = document.querySelectorAll('input[type=range]'), 
    prefs = ['webkit-slider-runnable', 'moz-range'], 
    styles = [], 
    l = prefs.length
    n = r.length;
document.body.appendChild(s);
var getTrackStyleStr = function(el) {
  var str = '', 
      j = el.dataset.idx, 
      min = el.min || 0, 
      perc = (el.max) ? ~~(100*(el.value - min)/(el.max - min)) : el.value, 
      val = perc + '% 100%';
  for(var i = 0; i < l; i++) {
    str += '.js input[type=range]:nth-of-type(' + j + ')::-' + prefs[i] + '-track{background-size:' + val + '}';
  }
  return str;
};
var getTipStyleStr = function(el) {
  var str = '.js input[type=range]:nth-of-type(' + el.dataset.idx + ') /deep/ #thumb:after{content:"' + el.value + '%"}';
  return str;
};
for(var i = 0; i < n; i++) {
  styles.push('');
  r[i].addEventListener('input', function() {    
    styles[this.dataset.idx] = getTrackStyleStr(this);
    if(this.classList.contains('tip')) {
      styles[this.dataset.idx] += getTipStyleStr(this);
    }
    s.textContent = styles.join('');
  }, false);
}
This works great for one range element but if I try adding more range elements on the same page, and change the data attribute to data-idx="2" it will not work, the first range will control them all.
How can I adjust the code to make each range work independently?
Here is a JSFiddle of the code I'm using, for some reason the javascript isn't working on there at all, but it's works fine on codepen? Hmm...
Here is the original Codepen
The <input type="range"> defines a control for entering a number whose exact value is not important (like a slider control). Default range is 0 to 100. However, you can set restrictions on what numbers are accepted with the attributes below. Tip: Always add the <label> tag for best accessibility practices!
For Chrome, use -webkit-appearance: slider-vertical . For IE, use writing-mode: bt-lr . For Firefox, add an orient="vertical" attribute to the html.
SOLUTION
var r = document.querySelectorAll('input[type=range]'), 
    prefs = ['webkit-slider-runnable', 'moz-range'], 
    styles = [], 
    l = prefs.length,
    n = r.length;
var getTrackStyleStr = function(el, j) {
  var str = '', 
      min = el.min || 0, 
      perc = (el.max) ? ~~(100*(el.value - min)/(el.max - min)) : el.value, 
      val = perc + '% 100%';
  el.previousElementSibling.textContent = el.value;
  
  for(var i = 0; i < l; i++) {
    str += "input[type=range][data-rangeId='" + j + "']::-" + prefs[i] + '-track{background-size:' + val + '} ';
  }
  return str;
};
var setDragStyleStr = function(evt) {
  var trackStyle = getTrackStyleStr(evt.target, this); 
  styles[this].textContent = trackStyle;
};
for(var i = 0; i < n; i++) {
  var s = document.createElement('style');
  document.body.appendChild(s);
  styles.push(s);
  r[i].setAttribute('data-rangeId', i);
  r[i].addEventListener('input', setDragStyleStr.bind(i));
}
html {
  background: #393939;
}
div {
  margin: 2.5em auto;
}
input[type='range'] {
  display: block;
  margin: 0.2em auto;
  border: solid .5em transparent;
  padding: 0;
  width: 15.5em;
  height: 1em;
  border-radius: .25em;
  background: transparent;
  font-size: 1em;
  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: 15.5em;
  height: 0.5em;
  border-radius: 0.25em;
  background: #fff;
}
input[type='range']::-webkit-slider-runnable-track {
  background: linear-gradient(#e44e4f, #e44e4f) no-repeat #fff;
}
input[type='range']::-moz-range-track {
  width: 15.5em;
  height: 0.5em;
  border-radius: 0.25em;
  background: #fff;
}
input[type='range']::-moz-range-track {
  background: linear-gradient(#e44e4f, #e44e4f) no-repeat #fff;
}
input[type='range']::-ms-track {
  border: none;
  width: 15.5em;
  height: 0.5em;
  border-radius: 0.25em;
  background: #fff;
  color: transparent;
}
input[type='range']::-ms-fill-lower {
  border-radius: 0.25em;
  background: #e44e4f;
}
input[type='range']::-webkit-slider-runnable-track {
  background-size: 0% 100%;
}
input[type='range']::-moz-range-track {
  background-size: 0% 100%;
}
input[type='range']::-webkit-slider-thumb {
  margin-top: -0.125em;
  border: none;
  width: 0.75em;
  height: 0.75em;
  border-radius: 50%;
  box-shadow: 0 0 0.125em #333;
  background: #fff;
}
input[type='range']::-moz-range-thumb {
  border: none;
  width: 0.75em;
  height: 0.75em;
  border-radius: 50%;
  box-shadow: 0 0 0.125em #333;
  background: #fff;
}
input[type='range']::-ms-thumb {
  border: none;
  width: 0.75em;
  height: 0.75em;
  border-radius: 50%;
  box-shadow: 0 0 0.125em #333;
  background: #fff;
}
input[type='range']::-ms-tooltip {
  display: none;
}
input[type='range']:focus {
  outline: none;
  box-shadow: 0 0 0.25em #e44e4f;
}
output[for='range'] {
  font-family: "Lucida Grande","Lucida Sans Unicode", Tahoma, Sans-Serif;
  font-size: 13px;
  color: white;
  display: block;
  text-align: center;
}
<div>
  <output for="range">0</output>
  <input type="range" value="0">
</div>
<div>
  <output for="range">0</output>
  <input type="range" value="0">
</div>
<div>
  <output for="range">0</output>
  <input type="range" value="0">
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With