2

I'm working with the range input here I'm trying to add color to the slider thumb before I had tried using background gradient but unable to achieve the desired output. when if I remove max="5" then its working fine. below is my code enter image description here

var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value;

slider.oninput = function() {
  output.innerHTML = this.value;
}
.slider {
  -webkit-appearance: none;
  width: 100%;
  height: 15px;
  border-radius: 5px;
  background: #d3d3d3;
  outline: none;
  opacity: 0.7;
  -webkit-transition: .2s;
  transition: opacity .2s;
}

.slider:hover {
  opacity: 1;
}

.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #4CAF50;
  cursor: pointer;
}

.slider::-moz-range-thumb {
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #4CAF50;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="slidecontainer">
  <input type="range" min="1" max="5" value="50" class="slider" id="myRange">
  <p>Value: <span id="demo"></span></p>
</div>
Husna
  • 1,286
  • 4
  • 19
  • 48
  • Your slider thumb has a green color, what are you trying to achieve here, exactly? – strwoc Feb 27 '20 at 08:22
  • @strwoci updated my question check now. I want to achieve that green color fill based on value – Husna Feb 27 '20 at 09:10
  • Does this answer your question? [How to style HTML5 range input to have different color before and after slider?](https://stackoverflow.com/questions/18389224/how-to-style-html5-range-input-to-have-different-color-before-and-after-slider) – strwoc Feb 27 '20 at 09:51
  • @strwoc I tried this code when I was increased with and slider thumb with border-radius is not working properly. according to my code, how should I achieve – Husna Feb 27 '20 at 09:55

2 Answers2

3

What you can do is to use a CSS linear-gradient() for the background of your range element. The gradient will look like this:

linear-gradient(90deg, #4CAF50 ${percentage}%, transparent ${percentage}%)

Where percentage is the abrupt transition point from your color green to transparent. To calculate this percentage, some math is required: you will want to calculate the relative value of the input element to its minimum and maximum values. This can be computed as such:

const percentage = (e.target.value - slider.min) / (slider.max - slider.min) * 100;

See proof-of-concept below:

var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value;

function updateGradient(rangeValue) {
  const percentage = (rangeValue - slider.min) / (slider.max - slider.min) * 100;
  slider.style.backgroundImage = `linear-gradient(90deg, #4CAF50 ${percentage}%, transparent ${percentage}%)`;
}

// Update gradient onload
updateGradient(slider.value);

// Update gradient oninput
slider.addEventListener('input', (e) => {
  output.innerHTML = e.target.value;
  updateGradient(e.target.value);
});
.slider {
  -webkit-appearance: none;
  width: 100%;
  height: 15px;
  border-radius: 5px;
  background: #d3d3d3;
  outline: none;
  opacity: 0.7;
  -webkit-transition: .2s;
  transition: opacity .2s;
}

.slider:hover {
  opacity: 1;
}

.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #4CAF50;
  cursor: pointer;
}

.slider::-moz-range-thumb {
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #4CAF50;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="slidecontainer">
  <input type="range" min="1" max="5" value="50" class="slider" id="myRange">
  <p>Value: <span id="demo"></span></p>
</div>

Even better: Use CSS custom properties / variables

Even better: you don't have to hardcode the color value in your JS, if you just use CSS variables/custom properties. In this case, we simply pass the calculated percentage as a string to the --percentage custom property:

background-image: linear-gradient(90deg, #4CAF50 var(--percentage), transparent var(--percentage));

Then, in your JS, it is as simply as doing this:

const percentage = (rangeValue - slider.min) / (slider.max - slider.min) * 100;
slider.style.setProperty('--percentage', percentage + '%');

See example below:

var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value;

function updateGradient(rangeValue) {
  const percentage = (rangeValue - slider.min) / (slider.max - slider.min) * 100;
  slider.style.setProperty('--percentage', percentage + '%');
}

// Update gradient onload
updateGradient(slider.value);

// Update gradient oninput
slider.addEventListener('input', (e) => {
  output.innerHTML = e.target.value;
  updateGradient(e.target.value);
});
.slider {
  -webkit-appearance: none;
  width: 100%;
  height: 15px;
  border-radius: 5px;
  background-color: #d3d3d3;
  background-image: linear-gradient(90deg, #4CAF50 var(--percentage), transparent var(--percentage));
  outline: none;
  opacity: 0.7;
  -webkit-transition: .2s;
  transition: opacity .2s;
}

.slider:hover {
  opacity: 1;
}

.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #4CAF50;
  cursor: pointer;
}

.slider::-moz-range-thumb {
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #4CAF50;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="slidecontainer">
  <input type="range" min="1" max="5" value="50" class="slider" id="myRange">
  <p>Value: <span id="demo"></span></p>
</div>
Terry
  • 63,248
  • 15
  • 96
  • 118
  • this my codepen https://codepen.io/Merajkhan/pen/JjdWJjB?editors=1010 here i'm trying to add according to my code can you check. – Husna Feb 27 '20 at 11:14
  • @Husna I don't understand how you've adapted my code to yours: you're missing out on the value calculation completely. If you log `this.value` it's returning the raw value, not the calculated percentage values. You should use `const percentage = (this.value - slider.min) / (slider.max - slider.min) * 100;` and then use `percentage` instead of `this.value` in your gradient color stop positions. – Terry Feb 27 '20 at 12:50
  • i got it i appreciate your effort. – Husna Feb 28 '20 at 06:31
1

Adding box-shadow to your thumb and make overflow hidden of the slider class is doing the job.

var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value;

slider.oninput = function() {
  output.innerHTML = this.value;
}
.slider {
  -webkit-appearance: none;
  width: 100%;
  height: 15px;
  border-radius: 5px;
  background: white;
  outline: none;
  opacity: 0.7;
  -webkit-transition: .2s;
  transition: opacity .2s;
  overflow:hidden;
}

.slider:hover {
  opacity: 1;
}

.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: yellow;
  cursor: pointer;
  box-shadow: -407px 0 0 407px green;
  z-index:2;
}

.slider::-moz-range-thumb {
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #4CAF50;
  cursor: pointer;
}
.input{
overflow:hidden;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="slidecontainer">
  <input type="range" min="1" max="5" value="50" class="slider" id="myRange">
  <p>Value: <span id="demo"></span></p>
</div>