This is an odd request; However, what would be the best method to display the value of an HTML5 range-slider on the thumb of the slider?! the thumb will be animated onLoad s
I too have had a lot of trouble figuring out a way to display the value of a range slider on its thumb. When working this out, I thought of three methods:
(Spoiler: Doesn't work - Read BoltClock's comment on the accepted answer of this thread)
body {
--thumbNumber: "5"; // updates on slider input via JavaScript function
}
#slider {
-webkit-appearance: none;
outline: none;
width: 400px;
height: 3px;
background-color: #555;
}
#slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 30px;
height: 30px;
cursor: pointer;
background: #5a5;
}
#slider::-webkit-slider-thumb::before { // doesn't work (refer to above link)
content: var(--thumbNumber);
}
window.onload = function () {
var slider = document.getElementById("slider");
slider.addEventListener("input", function () {
document.body.style.setProperty("--thumbNumber", "'" + this.value + "'");
});
// whenever this element receives input, change the value of --thumbNumber to this element's value
}
I thought I was pretty clever by using CSS variables to avoid the problem of not being able to directly change the properties of a pseudo-element in JavaScript. I learned, however, that this approach cannot work because you cannot use more than one pseudo-element selector in the same selection. (Refer to above link).
content
property with JavaScriptThis method is very similar to the previous one. The only difference is in the CSS. (Spoiler: This method also didn't work)
#slider::-webkit-slider-thumb {
content: var(--thumbNumber);
}
The JavaScript is the exact same as before. The idea is that the event listener attached to the slider element listens for input events, and reacts by changing the value of the CSS variable --thumbNumber
. This causes the content
property of the thumb to update and display the change. This doesn't work, however, because CSS doesn't seem to let you change the content
property of the thumb.
This is basically as bad as it gets when it comes to dirty solutions. This is completely unscalable, but it's only a little bit godawful when working with less than 10 numbers on an input range.
For this example, I made 10 png files in photoshop in about 10 minutes. Each file is a 30px by 30px image of a number on a transparent background. Their filenames are 1.png, 2.png, 3.png, and so on until 10.png. Each file is stored in a folder called png. This folder is located in the same folder as the html document.
body {
--sliderImage: url("png/5.png");
}
#slider::-webkit-slider-thumb {
background-image: var(--sliderImage);
}
window.onload = function () {
var slider = document.getElementById("slider");
slider.addEventListener("input", function () {
document.body.style.setProperty("--sliderImage", "url('png/" + this.value + ".png')");
});
}
This example is obviously terrible in so many ways, but it's all I've been able to try that has worked.
Basically, this makes it so that when the slider element receives input, the value of the CSS variable --sliderImage
is changed to, for example, url('png/6.png')
when the slider thumb is dragged onto the value 6. This causes the background-image
property of the thumb to update to a picture that correctly represents the value of the slider.
I am still searching for and trying to come up with an actual, reasonable answer to this problem. It puzzles me how such a seemingly simple task can, in reality, be very layered and difficult. I'll edit my answer as soon as I figure it out.