Where you’ll land
A slider and a video player from the same library, and the one thing they both tell you before you click.
A slider asks you to commit first and find out afterward. You press somewhere on the track, the value jumps, and only then do you learn whether that was the right place. The first one below is what you usually get. The second, Unlumen’s Slider, removes that step. Point at both and move around without pressing.
The second one draws the stretch between where you are and where you’d end up, and writes the value above your pointer. It doesn’t do anything yet. That’s the point.
Who does this, and who doesn’t
YouTube is the reason everybody knows this works. Point at its bar and a lighter stretch runs up to your pointer, with the time and a frame above it. You can look through an hour of video without losing your place, which is why scrubbing there feels safe.
MDNinput type=range, the slider browsers give you for free, tells you nothing until you’ve moved it. It’s what most settings pages still use, for volume or for brightness, and you only hear how loud that is once it’s that loud.
Spotify sits in between: when I point at the progress bar it lights up and shows its handle, so I know I can grab it, but not what’s at the spot under my pointer. For a three-minute song, that’s a fair call. For anything longer, you end up clicking and clicking again.
It previews where you’ll really land
The easy version follows the pointer. This one doesn’t, because a slider with steps can’t stop anywhere. The value under the pointer is snapped first, and the preview is drawn to that. In the demo above, the second slider moves in fives: watch the tip jump while your pointer glides.
const next = snap((cursor / width) * (max - min) + min);
const x = ((next - min) / (max - min)) * width;
const center = thumbX.get() + THUMB_SIZE / 2;
setPreview({ left: Math.min(center, x), width: Math.abs(x - center), onFilledSide: x < center, value: next, x });It also has two looks. Ahead of the thumb, the preview darkens the empty track, since that’s what you’d gain. Behind it, it lightens the filled part, since that’s what you’d lose. It’s the same bar saying opposite things, and you read it without thinking.
The track grows by two pixels under the pointer and the thumb goes from 14 to 18. That’s very little, and it’s enough to say “this one is awake.”
When the bar is the interface
Video Slider has the same idea with more room for it. Under the pointer the track goes from 6 pixels to 52, the round thumb becomes a tall thin bar, and the two timestamps slide inside. It stays out of the way while you’re watching, and it’s a proper tool once you reach for it. Here’s a canyon seen from a drone, to run your hand over.
The area you can grab is 80 pixels tall, much more than you can see. You should never have to aim at a video’s progress bar.
The bit nobody asked for
Drag past the end of the bar and it stretches, like something pulled a little too far, then snaps back. It doesn’t change the value. It tells you there’s no more video in that direction, in a way a dead stop doesn’t.
const EDGE_STRETCH_MAX_PX = 2000;
const EDGE_STRETCH_RESISTANCE_EXP = 0.5; // the further you pull, the less it gives
const strength = Math.pow(Math.min(1, overflow / EDGE_STRETCH_MAX_PX), EDGE_STRETCH_RESISTANCE_EXP);Every slider on this site is that Slider now: the song’s volume, its position in the player, every setting in these notes. There’s a real range input hidden under each one, so a keyboard or a screen reader never finds out about any of this.