Home > Software engineering >  How to add custom styles to input type="range"
How to add custom styles to input type="range"

Time:03-12

I have 4 custom input[type="range"] on my page. I used some JS and CSS to add styles, but it seems that only the first one works properly. What am I doing wrong and how to make all of them act like the first one? I don't want it to be like a regular range and I thought that JS CSS trick will be the best option. Nevertheless, if you know the way to make it work, I'll be glad to try it.

Here's the link to codepen: https://codepen.io/tomavl/pen/bGabZvj

var fillColor = "#9D3C3C",
  emptyColor = "#DDDDDD";

document
  .querySelector(".input-range--custom")
  .addEventListener("input", function () {
    var percent = (100 * (this.value - this.min)) / (this.max - this.min)   "%";
    //  this.setAttribute('value', this.value);
    //  this.setAttribute('title', this.value);
    this.style.backgroundImage = `linear-gradient( to right, ${fillColor}, ${fillColor} ${percent}, ${emptyColor} ${percent})`;
  });
input[type="range"].input-range--custom {
  -webkit-appearance: none;
  width: 100%;
  margin: 4px 0;
  background-image: linear-gradient(
      to right,
      rgb(157, 60, 60),
      rgb(157, 60, 60) 48%,
      rgb(221, 221, 221) 48%
    );
  border-radius: 20px 20px 0px 0px;
}

input[type="range"].input-range--custom:focus {
  outline: none;
}

input[type="range"].input-range--custom::-webkit-slider-runnable-track {
  width: 100%;
  height: 4px;
  cursor: pointer;
}

input[type="range"].input-range--custom:after {
  width: 20%;
  height: 4px;
  background-color: #9d3c3c;
}

input[type="range"].input-range--custom::-webkit-slider-thumb {
  height: 16px;
  width: 16px;
  border-radius: 15px;
  background: #ffffff;
  cursor: pointer;
  -webkit-appearance: none;
  margin-top: -5.5px;
  background: #9d3c3c;
  border: 2px solid #ffffff;
  box-sizing: border-box;
  box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.15);
}
<div >
  <h5>Distance</h5>
  <div  style="width: 280px">
    <label for="distance"></label>
    <input id="distance" type="range"  min="0" max="50">
  </div>
</div>

<div >
  <h5>Square</h5>
  <div  style="width: 280px">
    <label for="square"></label>
    <input id="square" type="range"  min="0" max="50">
  </div>
</div>

<div >
  <h5>Min height</h5>
  <div  style="width: 280px">
    <label for="minheight"></label>
    <input id="minheight" type="range"  min="0" max="50">
  </div>

</div>

<div >
  <h5>Max height</h5>
  <div  style="width: 280px">
    <label for="maxheight"></label>
    <input id="maxheight" type="range"  min="0" max="50">
  </div>
</div>

CodePudding user response:

Using document.querySelector(".input-range--custom"), you are selecting only the first input with the class input-range--custom.

So, the rest of the inputs do not have an event listener.

In order to select all of them, you need to use querySelectorAll instead of querySelector.

Replace your JS code with following:

var fillColor = "#9D3C3C",
  emptyColor = "#DDDDDD";

const rangeInputs = document.querySelectorAll(".input-range--custom")

rangeInputs.forEach(input => {
    input.addEventListener("input", function () {
      var percent = (100 * (this.value - this.min)) / (this.max - this.min)   "%";
      //  this.setAttribute('value', this.value);
      //  this.setAttribute('title', this.value);
      this.style.backgroundImage = `linear-gradient( to right, ${fillColor}, 
      ${fillColor} ${percent}, ${emptyColor} ${percent})`;
  });
})
  • Related