1 Pure CSS7 with JSPublished 2026-10-04Free · no sign-up
Eight range slider designs built on the native <input type="range">, which brings keyboard arrows, touch dragging and screen reader support for free. They include a filled track, a two-handle price filter, a labelled five-step scale, vertical mixer faders and a slider paired with a number box for exact values.
A native range input restyled for both WebKit and Firefox. The filled part of the track is a gradient whose stop follows the value through a custom property set by one line of JavaScript, and the thumb keeps a visible focus ring.
const r = document.getElementById('rs1'), o = document.getElementById('rs1o');
function paint() { r.style.setProperty('--v', r.value + '%'); o.textContent = r.value; }
r.addEventListener('input', paint);
paint();
02. Dual Thumb Price Range
FilterE-commerce
A minimum and maximum price filter made from two overlapping range inputs. Only the thumbs receive pointer events, a script stops the handles crossing, and both values are shown in text that updates as you drag.
A slider that snaps to five named steps, from Very unlikely to Very likely, with the labels printed under the track. A datalist supplies the tick marks, and aria-valuetext makes screen readers announce the words instead of the numbers 1 to 5.
Three vertical faders like an audio mixer. They use writing-mode: vertical-lr with direction: rtl so the value increases upwards, which keeps the native keyboard and screen reader support of a range input instead of rotating it with a transform.
A temperature control with a cold-to-hot gradient track and a white thumb that shows the current value in a bubble above it. The bubble is positioned with a custom property from the value and also printed as text for screen readers.
const t = document.getElementById('tmp'), out = document.getElementById('tmp-o');
function move() {
const p = (t.value - t.min) / (t.max - t.min);
t.parentElement.style.setProperty('--p', 'calc(' + (p * 100) + '% + ' + (12 - p * 24) + 'px)');
out.textContent = t.value + '°C';
}
t.addEventListener('input', move);
move();
06. Slider with Tick Scale
RangeScale
A zoom control with tick marks every 25 percent drawn by a repeating linear gradient under the track, plus minus and plus buttons for people who find dragging difficult. The buttons nudge the slider by one step and fire an input event.
A playful satisfaction slider where a face above the track changes from sad to delighted as the value rises. The face is decorative, while aria-valuetext gives a word for each step, so the meaning does not depend on the picture.
View code
<div class="emo">
<p class="face" aria-hidden="true">🙂</p>
<label for="emo-r">How was your delivery?</label>
<input id="emo-r" type="range" min="1" max="5" value="4" aria-valuetext="Good">
</div>
A slider paired with a number box so people can either drag roughly or type an exact value. Both controls stay in sync in either direction, share one visible label through aria-labelledby, and the number input enforces the same minimum and maximum.
Range inputs are styled through vendor pseudo-elements: ::-webkit-slider-thumb for Chrome, Edge and Safari, and ::-moz-range-thumb for Firefox. Set appearance: none on the input and on the WebKit thumb, then style both thumbs the same way.
Filling the track
There is no standard pseudo-element for the filled part of the track. These demos paint it with a linear gradient whose colour stop follows a custom property, updated from the input event with one line of JavaScript.
Words instead of numbers
If each step means something, such as Very unlikely to Very likely, set aria-valuetext so screen readers announce the words. Show the current value in visible text too, ideally in an <output> element linked to the slider.
Precision and motor access
Dragging a small thumb is hard for many people. Offer plus and minus buttons or a number input next to the slider, as the zoom and number pair demos do, and make the thumb at least 20 pixels across.
Frequently asked questions
How do I make a vertical slider?
Use writing-mode: vertical-lr with direction: rtl, as in the mixer demo, rather than rotating the input with a transform.
Can one input have two handles?
No. The price range overlays two range inputs and stops them crossing with a small script.
Do these work on touch screens?
Yes. Native range inputs support touch dragging in every mobile browser.