- ds
- Components
- Range and slider
Range and slider
A native range in the accent, with its value and tick marks.
Range
Code
<input class="range" type="range" min="0" max="100" value="40" aria-label="Opacity" style="max-width:20rem" />A native input type="range" with its own track and thumb: a 4px track, a 14px thumb ringed in the accent, a soft halo on hover and a ring on the thumb for keyboard focus. It is still the native control, so arrow keys, Page Up and Down, touch and screen readers all work. On touch screens the thumb grows to 18px.
The fill
Firefox draws the filled part of the track by itself. Chrome and Safari cannot, so the fill comes from --v, the value as a number from 0 to 1. ds.css reads it; three lines of script keep it current.
const fill = (r) => r.style.setProperty('--v', (r.value - r.min) / (r.max - r.min));
document.querySelectorAll('input.range').forEach(fill);
addEventListener('input', (e) => e.target.matches?.('input.range') && fill(e.target));With a label and value
Code
<div class="slider" style="max-width:26rem">
<label for="r-speed">Speed</label>
<input id="r-speed" class="range" type="range" min="0.25" max="2" step="0.25" value="1" />
<output for="r-speed">1×</output>
</div>
<div class="slider stack" style="max-width:18rem">
<label for="r-pad">Padding</label>
<input id="r-pad" class="range" type="range" min="0" max="48" step="4" value="16" />
<output for="r-pad">16 px</output>
</div>.slider puts the label, the range and the value in one row. .stack moves the label and value above the range, which suits narrow side panels.
Tick marks
Code
<div class="slider" style="max-width:26rem">
<label for="r-step">Bucket</label>
<input id="r-step" class="range" type="range" min="0" max="4" step="1" value="2" aria-valuetext="1 hour" />
<output for="r-step">1 h</output>
<div class="range-ticks" aria-hidden="true"><span>5m</span><span>15m</span><span class="on">1h</span><span>6h</span><span>1d</span></div>
</div>Ticks are spread evenly and inset by half a thumb, so each one sits under the thumb's centre at its value. Give every step a tick when there are only a few. On a long range, label the ends and a few round numbers. .on marks the current tick.
API
| Class | On | What it does |
|---|---|---|
.range | input[type=range] | Track, fill and thumb. Works with min, max and step as usual. |
--v | .range or a parent | The value from 0 to 1, for the fill in Chrome and Safari. |
--range-thumb / --range-track | .range and its ticks | Thumb size (0.875rem) and track height (0.25rem). Set them on a parent so ticks follow. |
.slider | div | Label, range and value in a row. |
.stack | .slider | Label and value above the range. |
output / .val | .slider > * | The value: mono, tabular figures, right-aligned. |
.range-ticks | div | Evenly spaced ticks under a range. .on marks the current one. |
Accessibility
- Label every range with a
labeloraria-label. When the number alone does not say it, setaria-valuetext: "1 hour", "4.2 seconds of 12". - Show the value in an
outputtied to the input withfor. - Ticks are decoration and carry
aria-hidden; the value text carries the meaning.