Starting Point
v0.25.0
Start typing to search...
Go to Page
escClose

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.

ClassDescription
sliderAdd to an <input type="range">
slider-verticalAdd to slider for a bottom-to-top slider
slider-rangeAdd to a wrapper around several sliders for a multi-thumb range
<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.

<div class="slider-range" style="--val-min: 25%; --val-max: 50%">
  <input
    type="range"
    class="slider"
    max="100"
    step="5"
    value="25"
    aria-label="Minimum"
  />
  <input
    type="range"
    class="slider"
    max="100"
    step="5"
    value="50"
    aria-label="Maximum"
  />
</div>

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.

<input
  type="range"
  class="slider"
  max="100"
  step="1"
  value="50"
  style="--val: 50%"
  disabled
  aria-label="Value"
/>

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();