Slider

A Tailwind CSS slider component for selecting a value from a range.

<input
  type="range"
  class="slider"
  min="0"
  max="100"
  value="50"
  style="--val: 50%"
/>

With label

Pair with a Label for accessible form fields. Connect them using matching for and id attributes so screen readers announce the control correctly.

<div class="w-full max-w-xs">
  <div class="grid gap-3">
    <label class="label" for="volume">Volume</label>
    <input
      type="range"
      class="slider"
      id="volume"
      name="volume"
      min="0"
      max="100"
      value="60"
      style="--val: 60%"
    />
  </div>
</div>

With value

Show the current value alongside the slider. Add data-sp-slider-value to any element and point it at the slider's id — the library keeps its text content in sync with the slider.

75
<div class="w-full max-w-xs">
  <div class="grid gap-3">
    <div class="flex items-center justify-between">
      <label class="label" for="brightness">Brightness</label>
      <span
        class="text-sm text-muted-foreground"
        data-sp-slider-value="brightness"
      >
        75
      </span>
    </div>
    <input
      type="range"
      class="slider"
      id="brightness"
      name="brightness"
      min="0"
      max="100"
      value="75"
      style="--val: 75%"
    />
  </div>
</div>

Stepped

Use the step attribute to snap to discrete values.

250
<div class="w-full max-w-xs">
  <div class="grid gap-3">
    <div class="flex items-center justify-between">
      <label class="label" for="price">Max price</label>
      <span class="text-sm text-muted-foreground" data-sp-slider-value="price">
        250
      </span>
    </div>
    <input
      type="range"
      class="slider"
      id="price"
      name="price"
      min="0"
      max="500"
      step="25"
      value="250"
      style="--val: 50%"
    />
  </div>
</div>

Disabled

Add disabled to the slider and peer so the label dims to match.

<div class="w-full max-w-xs">
  <div class="grid gap-3">
    <label class="label peer-disabled:opacity-50" for="disabled-slider">
      Disabled slider
    </label>
    <input
      type="range"
      class="slider peer"
      id="disabled-slider"
      name="disabled-slider"
      min="0"
      max="100"
      value="40"
      style="--val: 40%"
      disabled=""
    />
  </div>
</div>

How it works

The slider component is a utility class applied to a native <input type="range"> element. The filled portion of the track is painted using a --val CSS variable, which the library's JavaScript keeps in sync with the input's current value.

Structure

Use the .slider class on an <input type="range">. Always set min, max, and value — the library uses them to compute the fill width. Pair with a .label element connected via for and id, and set the initial fill by passing --val as an inline style matching the initial value:

<label class="label" for="volume">Volume</label>
<input
  type="range"
  class="slider"
  id="volume"
  min="0"
  max="100"
  value="50"
  style="--val: 50%"
/>

The library updates --val automatically whenever the user interacts with the slider, and also when the value, min, or max attributes change programmatically. The inline --val only matters for the initial render — without it, the fill would flash empty until the JavaScript runs.

Displaying the current value

To show the slider's value in another element, add data-sp-slider-value pointing at the slider's id. The library keeps the element's text content in sync with the slider as it changes:

<span data-sp-slider-value="volume">50</span>
<input type="range" class="slider" id="volume" value="50" style="--val: 50%" />

Disabled state

Add disabled to the slider. Use peer on the slider so the label automatically dims via peer-disabled:

<input type="range" class="slider peer" id="sl" disabled />
<label class="label peer-disabled:opacity-50" for="sl">Disabled</label>

Class reference

ClassDescription
sliderBase slider styles