How to change the input slider thumb colour depending on value?

前端 未结 4 1459
小蘑菇
小蘑菇 2021-01-24 11:03

I\'m making a site that includes a range input slider. I would like the slider thumb to change colour according to the value of the slider.

For example, if the value was

相关标签:
4条回答
  • 2021-01-24 11:45

    the simplest is to use a variable css. see : https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties

    const Slider = document.querySelector('input[name=rangeInput]')
    
    Slider.oninput =_=> Slider.style.setProperty('--SliderColor', `hsl(${Slider.value}, 100%, 50%)`)
    .slidecontainer {
      transform: translateY(-10px);
      text-align: center;
    }
    .slider {
      --SliderColor: hsl(50, 100%, 50%);
      -webkit-appearance: none;
      width: 60%;
      margin: 50px auto;
      height: 8px;
      border-radius: 4px;
      margin-bottom: 15px;
      background-color: rgb(200, 200, 200);
    }
    
    /* --------------------------- webkit browsers */
    .slider::-webkit-slider-thumb {
      -webkit-appearance: none;
      width: 18px;
      height: 18px;
      border-radius: 10px;
      background-color: var(--SliderColor);
      overflow: visible;
      cursor: pointer;
    }
    /* -------------------------- Firefox */
    .slider::-moz-range-thumb { 
      -moz-appearance: none;
      width: 18px;
      height: 18px;
      border-radius: 10px;
      background-color: var(--SliderColor);
      overflow: visible;
      cursor: pointer;
    }
    .slider::-moz-focus-outer { border: 0; }
    /* Remove dotted outline from range input element focused in Firefox */
    <div class="slidecontainer">
      <input type="range" min="0" max="100" value="50" class="slider" name="rangeInput">
    </div>

    [edit]: adding css .slider::-moz-range-thumb (Firefox)

    0 讨论(0)
  • 2021-01-24 11:49

    This is how I would do it: I would create a new <style> element and I woild append this element to the head. Next on input I would write a css rule that would change the thumb's color from red to green using hsl colors. I would make this css rule the text content of the new style element. I hope it helps.

    let s = document.createElement("style");
    document.head.appendChild(s);
    itr.addEventListener("input", () => {
      s.textContent = `.slider::-webkit-slider-thumb{background-color: hsl(${itr.value}, 100%, 50%)}`
    })
    .slider {
      width: 60%;
      margin: 50px auto;
      -webkit-appearance: none;
      height: 8px;
      border-radius: 4px;
      margin-bottom: 15px;
      background-color: rgb(200, 200, 200);
    }
    
    .slider::-webkit-slider-thumb {
      -webkit-appearance: none;
      width: 18px;
      height: 18px;
      border-radius: 10px;
      background-color: hsl(50, 100%, 50%);
      overflow: visible;
      cursor: pointer;
    }
    
    .slidecontainer {
      transform: translateY(-10px);
    }
    <div class="slidecontainer" align="center">
      <input id="itr" type="range" min="0" max="100" value="50" class="slider" name="rangeInput">
    </div>

    0 讨论(0)
  • 2021-01-24 12:03

    Your post looks similar to this one: .slider::-webkit-slider-thumb needed in javascript

    const range = document.getElementById("rangeInput");
    var style = document.querySelector('[data="test"]');
    
    range.addEventListener("input", () => {
       const slider_value = range.value;
       let thumb_color;
       if (slider_value <= 29) {
           thumb_color = "rgb(255, 0, 0)";
       }
       else if (slider_value >= 30 && slider_value <= 69) {
           thumb_color = "rgb(255, 255, 0)";
       }
       else {
           thumb_color = "rgb(0, 255, 0)";
       }
       style.innerHTML = `.slider::-webkit-slider-thumb { background-color: ${thumb_color} !important; } .slider:-moz-range-thumb {  ${thumb_color} !important; }`;
    });
    .slider {
        width: 60%;
        margin: 50px auto;
        -webkit-appearance: none;
        height: 8px;
        border-radius: 4px;
        margin-bottom: 15px;
        background-color: rgb(200, 200, 200);
    }
    
    .slider::-webkit-slider-thumb {
       -webkit-appearance: none;
        width: 18px;
        height: 18px;
        border-radius: 10px;
        background-color: rgb(255, 120, 0);
        overflow: visible;
        cursor: pointer;
        transition: all 1s ease;
            
    }
    
    .slidecontainer {
        transform: translateY(-10px);
    }
    <style data="test" type="text/css"></style>
    
    <div class="slidecontainer" align="center">
        <input id="rangeInput" type="range" min="0" max="100" value="50" class="slider" name="rangeInput">
    </div>

    0 讨论(0)
  • 2021-01-24 12:05

    You're basically looking for this, right?

    const input = document.querySelector('input[type="range"]');
    const style = document.createElement('style');
    const head = document.head || document.getElementsByTagName('head')[0];
    style.type = 'text/css';
    head.appendChild(style);
    input.oninput = function(e) {
      const cssText = `input.slider::-webkit-slider-thumb, input.slider::-moz-range-thumb {
        background-color: rgb(${255 - 2.55*e.target.value}, ${2.55*e.target.value}, 0);
      }`;
      if (style.styleSheet) {
        style.styleSheet.cssText = cssText;
      } else {
        style.innerHTML = "";
        style.appendChild(document.createTextNode(cssText));
      }
    }
    .slider {
      width: 60%;
      margin: 50px auto;
      -webkit-appearance: none;
      height: 8px;
      border-radius: 4px;
      margin-bottom: 15px;
      background-color: rgb(200, 200, 200);
    }
    
    .slider::-webkit-slider-thumb, 
    .slider::-moz-range-thumb {
      -webkit-appearance: none;
      width: 18px;
      height: 18px;
      border-radius: 10px;
      background-color: rgb(128, 128, 0);
      overflow: visible;
      cursor: pointer;
    }
    
    .slidecontainer {
      transform: translateY(-10px);
    }
      <div class="slidecontainer" align="center">
        <input type="range" min="0" max="100" value="50" class="slider" name="rangeInput" oninput="test">
      </div>

    It's a bit trickier as ::webkit-slider-thumb is a pseudo element and (i might be wrong here) i don't think you can target it directly with JavaScript. So what I did was add a <style> tag to <head> and dynamically change its contents based on current input value, in a function triggered on input event.

    It's more of a proof of concept, it can be improved by using addEventListener and it probably looks prettier in jQuery. I'll leave all that jazz to you.


    Edit: As exaneta's answer points out, you have a range of options when dealing with dynamically changing colors. While I used a simple 255 > 0 for red and 0 > 255 for green in an rgb(), you might want to use exaneta's solution: hsl(${e.target.value}, 100%, 50%).

    0 讨论(0)
提交回复
热议问题