Slider
Styled native <input type="range"> (Material's Slider, Lozenge-flavoured): chunky 16px pill track with a LIVE fill that requires no wiring — the fill is welded to the thumb (clipped one-sided thumb shadow on WebKit/Blink, ::-moz-range-progress on Firefox), so dragging, keyboard steps, and programmatic value changes all move it with zero JS and zero custom properties. Behavior is 100% the platform's. The legacy 4px hairline look is available as .slider-thin, whose fill IS driven by an app-set --value (0..1) — that limitation applies only to the thin variant.
Root: .slider on <input>
Examples
<input type="range" class="slider" min="0" max="100" value="60" aria-label="Estimate">
<input type="range" class="slider slider-compact" min="0" max="10" value="3" aria-label="Story points">
<div class="range-slider"><input type="range" class="slider" min="0" max="100" value="20" aria-label="Minimum"><input type="range" class="slider" min="0" max="100" value="60" aria-label="Maximum"></div>
Contract
Variants & modifiers
| Class | Axis | Rules |
|---|---|---|
slider-compact | size | optional · exclusive |
slider-thin | form | optional · exclusive |
slider-compact | modifier | optional |
slider-thin | modifier | optional |
Accessibility
| On | Attribute | Level | When |
|---|---|---|---|
.slider | aria-label | required | no visible <label for> or aria-labelledby references the input |
All interaction is the native range input: arrow keys step, Home/End jump, drag works, form participation is standard. Name the control with a visible <label for> or aria-label. Forced-colors mode reverts to the stock control via accent-color. For .slider-thin only: keep --value in sync with app code or accept an unfilled track.
Nesting
Allowed in:
forms.form-grouptoolbarscard bodies.range-slider
Subcomponents
Range-slider
Dual-thumb range (Material's RangeSlider), zero JS: two stacked native range inputs inside a .range-slider container; each thumb's shadow masks outward so the between-region stays accent-filled. Each thumb keeps its own tab stop, label, and ARIA slider semantics. The app enforces min<=max on submit (the paint is agnostic).
Root: .range-slider on <div>
Example
<div class="range-slider"><input type="range" class="slider" min="0" max="100" value="20" aria-label="Minimum"><input type="range" class="slider" min="0" max="100" value="60" aria-label="Maximum"></div>
Structure
| Selector | Required | Description |
|---|---|---|
.slider | required | Exactly two input.slider children (min then max, document order determines mask direction). |
Accessibility
| On | Attribute | Level | When |
|---|---|---|---|
.range-slider > .slider | aria-label | required | each input needs its own name, e.g. Minimum/Maximum |
Two real inputs: both are keyboard-reachable in document order. Under forced-colors the container unstacks into two labeled native sliders.
Nesting
Allowed in:
forms.form-group
Never inside (or containing):
.range-slider