I've looked all over Stackoverflow and it seems that all range sliders with thumb labels have this problem. For example, this answer almost doesn't have it, but still does.
Basically, you can calculate value / max
to get the left
style for the range value label, so that it's always aligned to the thumb.
The problem is that the further right you slide, the more offset it gets. For example, in the linked answer the label starts off on the left side of the thumb at the 0 value, and it slowly slides to the right side of the thumb by the time it gets to 100.
Why is this happening? I'm implementing my own solution and it suffers from this problem. Also, every answer I've seen on Stackoverflow has this problem. What's causing it, and is there a good solution?
Here's a shitty GIF of the problem:
This is happening because the dot's center does not represent the value. Lets say the dot's size is 10px and the slider is 100px wide. When slider value is 0, the center of the dot is actually at 0px + 5px
, i.e. 0 * slider_width + 0.5 * dot_width
. When the slider is at 100% then the center of the dot is at 100px - 5px
, i.e. 1 * slider_width - 0.5 * dot_width
.
To fix this issue you need to subtract an offset value of (percent_as_decimal - 0.5) * dot_width
. This will be negative when less than 50% so when subtracted it will add.
Now that above offset will only affect where the leftside of the element is placed. You will also need to place a translate of 50%, via transform: translateX(-50%);
to the number's container to address the width of the number element.
To summarize:
1) align left side of number to center of dot
2) translate number to place the center of the number with where the left side was before.