I needed a slider to select a color. I found a solution and changed it a bit: https://codepen.io/hobuttt/pen/zLoyWx The problem is this: the slider should be painted in the selected color. In the found version is used:

if (typeof InstallTrigger !== 'undefined') { var stylesheet = document.styleSheets[0]; stylesheet.insertRule('input[type=range]::-moz-range-thumb { background: ' + bkgColor + ' }', stylesheet.cssRules.length); } else { document.styleSheets[0].addRule('input[type=range]::-webkit-slider-thumb', 'background-color: ' + bkgColor); } 

But in real life it does not work: enter image description here

Appeal via querySelector also does not work. Does anyone have any options, how can this be solved?

  • If you are looking for a cross-browser solution, then the native input type = range is not suitable. I in a similar case use SVG. - Stranger in the Q
  • And why does this code work in codepen? - Evgeniy

1 answer 1

I do not see the problem, the code is working. If necessary, add rules for IE. Also note that in all browsers except prefixes, the way styles are applied varies greatly. For example, in Chrome the border is located inside the slider, and in Mozille outside.

 // safari needs window.onload window.onload = function() { // create a <canvas> element to hold the color gradient var canvas = document.createElement('canvas'); // range is 208-40=168, add 1 so range value stays inside the canvas canvas.width = 169; canvas.height = 1; // create a 2d context var canvasContext = canvas.getContext("2d"); // create linear gradient specify x,y,width,height var gradient = canvasContext.createLinearGradient(0, 0, canvas.width, canvas.height); // define colors to add - can use any color format but must be in quotes gradient.addColorStop(0, "#ff0000"); gradient.addColorStop(.17, "#ff00ff"); gradient.addColorStop(.33, "#0000ff"); gradient.addColorStop(.50, "#00ffff"); gradient.addColorStop(.67, "#00ff00"); gradient.addColorStop(.83, "#ffff00"); gradient.addColorStop(1, "#ff0000"); // use the gradient as a fill canvasContext.fillStyle = gradient; // draw the fill onto the canvas, specify x,y,width,height canvasContext.fillRect(0, 0, canvas.width, canvas.height); var thumb = document.getElementById("slider"); // updates the thumb colors while you drag the thumb, not sure why 'drag' event didn't work here thumb.addEventListener('mousemove', function() { changeColors(); }); // if 'mousemove' is too fast sometimes value and color won't // match up with thumb position, so update just in case thumb.addEventListener('change', function() { changeColors(); }); // display initial value var circle = document.getElementById("circle"); circle.innerHTML = thumb.value; // amount to increment/decrement // google's metronome uses 2, 3, and 4 steps var steps = 2; // decrement when minus is clicked var minus = document.getElementById("minus"); minus.addEventListener('click', function() { thumb.value = Number(thumb.value) - steps; changeColors(); }); // increment when plus is clicked var plus = document.getElementById("plus"); plus.addEventListener('click', function() { thumb.value = Number(thumb.value) + steps; changeColors(); }); // run it once to set colors changeColors(); // set the rgb values from <canvas> using x, y coordinates function changeColors() { //range starts at 40 so subtract 40 var xCoord = thumb.value - 40; // get the color data from the canvas var rgbValues = canvas.getContext('2d').getImageData(xCoord, 0, 1, 1).data; var bkgColor = "rgb(" + rgbValues[0] + ", " + rgbValues[1] + ", " + rgbValues[2] + ")"; // display thumb value circle.innerHTML = thumb.value; // set colors circle.style.backgroundColor = bkgColor; minus.style.color = bkgColor; plus.style.color = bkgColor; // dynamically change color of thumb pseudo-element by adding new styles // test for Firefox API or else thumb won't change colors var stylesheet = document.styleSheets[0]; if (typeof InstallTrigger !== 'undefined') { stylesheet.insertRule('input[type=range]::-moz-range-thumb { border-color: ' + bkgColor + ' }', stylesheet.cssRules.length); } else { stylesheet.addRule('input[type=range]::-webkit-slider-thumb', 'border-color: ' + bkgColor); } } } 
 #circle { width: 100px; height: 100px; border-radius: 50%; color: #FFF; font-weight: bold; font-family: sans-serif; font-size: 30px; text-align: center; line-height: 100px; } #slider { width: 420px; } #minus, #plus { font-weight: bold; font-size: 30px; cursor: pointer; -webkit-user-select: none; /* Chrome/Safari/Opera */ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* Internet Explorer/Edge */ } #slider { -webkit-appearance: none; -moz-appearance: none; outline: none; } #slider::-webkit-slider-runnable-track { width: 300px; height: 4px; background: linear-gradient(to left, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); border: none; border-radius: 3px; margin-top: -15px; } #slider::-moz-range-track { width: 420px; height: 4px; background: linear-gradient(to left, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); border: none; border-radius: 3px; margin-top: -15px; } #slider::-webkit-slider-thumb { -webkit-appearance: none; background: #fff; border-width: 4px; border-style: solid; height: 20px; width: 20px; border-radius: 50%; margin-top: -8px; } #slider::-moz-range-thumb { -moz-appearance: none; background: #fff; border-width: 4px; border-style: solid; height: 12px; width: 12px; border-radius: 50%; margin-top: -8px } canvas { border: solid 1px #f00; display: block; margin: 20px 0; } 
 <div id="circle"></div> <div id="range"> <span id="minus">&minus; </span><input id="slider" value="128" type="range" min="40" max="208" step="2"><span id="plus"> &plus;</span> </div> 

It was also noticed (in versions of browsers earlier than actual ones) that when styling native elements, it is better not to use common properties (for example, border: width style color; ), but to split them into separate ones ( border-width: ... and t .d.)