Slider

Sets a number by dragging along a track, like volume or a daily limit.

Examples

Monthly savings

150

Spending range

120 to 340

Thumbs

  • 150

    onedefault

  • 120 to 340

    two

Show value

  • falsedefault

  • 150

    true

States

  • 150

    rest

  • 150

    hover

  • 150

    focus-visible

  • 150

    disabled

Usage

When to use it
Use
A number on a range where the rough position matters: a monthly amount, a spending cap.
Use
A start and an end, as a range with two thumbs.
Not for
The exact number matters, such as an amount. Use Input.
Not for
There are two to five named choices. Use Segmented.

Rules

8 rules
Should
Set showValue when the number matters; the thumb gives only the rough position.
Must
Pass thumbLabels on a two-thumb slider so the thumbs differ. Because otherwise a screen reader announces two thumbs with the same name.
Must
Pass an aria-label that names the value and its unit. Because a screen reader reads 150 alone, and dollars, days and percent sound the same.
Should
Set step when only some numbers make sense; do not round after the drag.
Should
Save in onValueCommitted once at the end of a drag, not on every move.
Never
Recolor the track or add a gradient; the fill is lime and the track grey. Because a gradient blurs where the lime fill ends, which is where the value is.
Should
Leave vertical room around the slider on a phone; touch-none lets a finger drag the thumb, not scroll.
Never
Render a slider whose min equals max; show the number instead. Because the thumb has no travel, so every drag and arrow key does nothing.

Accessibility

5 checks
Each thumb is role slider with aria-valuenow, min and max; the group is named by aria-label.
Arrows step by step; Page keys and Shift move by ten steps; Home and End jump to the ends.
Forced colors paints the track GrayText and the fill Highlight.
The 20px thumb is under 44px; add room around it on a phone.
Base UI reads direction from DirectionProvider, so wrap RTL pages in it.

Edge cases

6 edge cases
Narrow container
The track follows the container; the value keeps its width and the track gives way.
Right to left
Under a DirectionProvider the fill grows from the right and the value sits at the end; without one it stays left to right.
Long range label
The value keeps a 40px floor and shortens the track.
No defaultValue
The one thumb sits at the minimum.
Inside a form
The value submits through hidden inputs under the name.
Reduced motion
No hover or drag scale on the thumb.

API

5 props
value, defaultValue
number[]
onValueChange, onValueCommitted
(value: number[]) => void
min, max, step
number default 0, 100, 1
thumbLabels
string[]
showValue
boolean default false

Tokens

15 tokens
--surface-3
#e6e4df
--accent
#e4f222
--accent-line
#7c8700
--fg-disabled
#a6a49b
--page
#ffffff
--ink
#0f0f0d
--shadow-card
0 1px 2px rgb(var(--shadow-ink) / 0.06), 0 1px 1px rgb(var(--shadow-ink) / 0.04)
--line-strong
#cfcdc6
--ring
var(--accent-line)
--line-focus
2px
--focus-offset
2px
--dur-fast
140ms
--ease-out
cubic-bezier(0.16, 1, 0.3, 1)
--text-sm
14px
--weight-medium
500

Install

For your coding agent

GitHub

Please star me pookie

141

A new design system every week

Leave your email before you copy the prompt.