Slider
The slider picks a numeric value from a range by dragging a thumb along a track, like volume or a price cap.
<div class="field">
<span class="field-title">Volume</span>
<p class="field-description">
Set the playback volume (
<span
class="font-medium tabular-nums"
data-sp-slider-value="slider-demo-volume"
>
75
</span>
%).
</p>
<input
type="range"
class="slider mt-2"
id="slider-demo-volume"
max="100"
step="1"
value="75"
style="--val: 75%"
aria-label="Volume"
/>
</div>Usage
Add the slider class to an <input type="range">. The filled part of the track follows the value; set the inline --val to match the initial value so the fill paints correctly before JavaScript loads.
<input
type="range"
class="slider"
min="0"
max="100"
value="50"
style="--val: 50%"
/>Examples
Range
Overlay two sliders in a slider-range to pick a range with two thumbs; the wrapper paints the shared fill and keeps the thumbs from crossing.
Multiple thumbs
The wrapper takes any number of sliders; each thumb is clamped between its neighbors.
<div class="slider-range" style="--val-min: 10%; --val-max: 70%">
<input
type="range"
class="slider"
max="100"
step="10"
value="10"
aria-label="First value"
/>
<input
type="range"
class="slider"
max="100"
step="10"
value="20"
aria-label="Second value"
/>
<input
type="range"
class="slider"
max="100"
step="10"
value="70"
aria-label="Third value"
/>
</div>Vertical
Add slider-vertical for a bottom-to-top slider.
<div class="flex items-center justify-center gap-6">
<input
type="range"
class="slider slider-vertical"
max="100"
step="1"
value="50"
style="--val: 50%"
aria-label="Value"
/>
<input
type="range"
class="slider slider-vertical"
max="100"
step="1"
value="25"
style="--val: 25%"
aria-label="Value"
/>
</div>Controlled
Point an element at the slider with data-sp-slider-value and it mirrors the value automatically.
<div class="grid gap-3">
<div class="flex items-center justify-between gap-2">
<label class="label" for="slider-temperature">Temperature</label>
<span
class="text-sm text-muted-foreground tabular-nums"
data-sp-slider-value="slider-temperature"
>
0.3
</span>
</div>
<input
type="range"
class="slider"
id="slider-temperature"
min="0"
max="1"
step="0.1"
value="0.3"
style="--val: 30%"
/>
</div>Field
Wrap the slider in a field with a title and description.
<div class="field">
<span class="field-title">Price Range</span>
<p class="field-description">
Set your budget range ($
<span
class="font-medium tabular-nums"
data-sp-slider-value="slider-price-min"
>
200
</span>
-
<span
class="font-medium tabular-nums"
data-sp-slider-value="slider-price-max"
>
800
</span>
).
</p>
<div class="slider-range mt-2" style="--val-min: 20%; --val-max: 80%">
<input
type="range"
class="slider"
id="slider-price-min"
max="1000"
step="10"
value="200"
aria-label="Minimum price"
/>
<input
type="range"
class="slider"
id="slider-price-max"
max="1000"
step="10"
value="800"
aria-label="Maximum price"
/>
</div>
</div>Steps
Use step to snap the value to increments.
<div class="field">
<span class="field-title">Zoom</span>
<p class="field-description">
Snaps in steps of 25 (
<span
class="font-medium tabular-nums"
data-sp-slider-value="slider-steps-zoom"
>
50
</span>
%).
</p>
<input
type="range"
class="slider mt-2"
id="slider-steps-zoom"
min="0"
max="100"
step="25"
value="50"
style="--val: 50%"
aria-label="Zoom"
/>
</div>Disabled
Add disabled and the slider mutes itself and blocks interaction.
JavaScript
Events
The slider is a native input, so listen to the native events: input fires on every change while dragging, change once the value settles.
slider.addEventListener("input", (e) => {
console.log(e.target.value);
});Methods
The fill updates on init and on user input. After changing value, min, or max programmatically, refresh with update():
const slider = document.querySelector("#volume");
slider.value = "90";
sp.slider(slider).update();