Range
A native range, painted with the same rail, fill and thumb as the slider, so it matches Kobalte's Slider.
alpha The class names and states here are stable. The look is not: these styles can change in a minor release, without a major version bump.
| Class | Does what |
|---|---|
range | A native range with the slider's rail, fill and thumb |
Basic
<label class="label">
Volume
<input type="range" class="range" min="0" max="100" value="60" style="--range-fill: 60%" />
</label>
<label>
Volume
<input type="range" min="0" max="100" value="60" style="--range-fill: 60%" />
</label>
import { Slider } from "@kobalte/core/slider";
<Slider class="slider" value={volume()} onChange={setVolume}>
<Slider.Label>Volume</Slider.Label>
<Slider.Track class="slider-track">
<Slider.Fill class="slider-fill" />
<Slider.Thumb>
<Slider.Input />
</Slider.Thumb>
</Slider.Track>
</Slider>
<div class="slider" role="group">
<label>Volume</label>
<div class="slider-track">
<div class="slider-fill" style="left: 0%; right: 40%"></div>
<span role="slider" aria-valuenow="60" style="position: absolute; left: calc(60%); transform: translateX(-50%)"><input style="border: 0; clip: rect(0 0 0 0); clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; white-space: nowrap; width: 1px" /></span>
</div>
</div>
Keeping the fill in step
Firefox draws the fill itself. Chrome and Safari have no pseudo-element for it,
so the fill reads --range-fill, which has to follow the value:
<input
type="range"
class="range"
value="60"
style="--range-fill: 60%"
oninput="this.style.setProperty('--range-fill', this.value + '%')"
/>
That assumes a 0 to 100 range. For any other min and
max, set it to (value - min) / (max - min) as a
percentage.
Disabled
<input type="range" class="range" value="60" style="--range-fill: 60%" disabled />
<input type="range" value="60" style="--range-fill: 60%" disabled />
<Slider class="slider" disabled value={[60]}>
<Slider.Track class="slider-track">
<Slider.Fill class="slider-fill" />
<Slider.Thumb>
<Slider.Input />
</Slider.Thumb>
</Slider.Track>
</Slider>
<div class="slider" role="group" data-disabled>
<div class="slider-track">
<div class="slider-fill" style="left: 0%; right: 40%"></div>
<span role="slider" aria-valuenow="60" aria-disabled="true" style="position: absolute; left: calc(60%); transform: translateX(-50%)"><input style="border: 0; clip: rect(0 0 0 0); clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; white-space: nowrap; width: 1px" disabled /></span>
</div>
</div>