File: slider.md | Updated: 11/15/2025
ThemesThemes PrimitivesPrimitives IconsIcons ColorsColors
Documentation Case studies Blog
Search
/
Introduction Getting started Accessibility Releases
Styling Animation Composition Server-side rendering
Accordion
Alert Dialog
Aspect Ratio
Avatar
Checkbox
Collapsible
Context Menu
Dialog
Dropdown Menu
Form
Preview
Hover Card
Label
Menubar
Navigation Menu
One-Time Password Field
Preview
Password Toggle Field
Preview
Popover
Progress
Radio Group
Scroll Area
Select
Separator
Slider
Switch
Tabs
Toast
Toggle
Toggle Group
Toolbar
Tooltip
Accessible Icon Direction Provider Portal Slot Visually Hidden
Components
An input where the user selects a value from within a given range.
index.jsxindex.jsxstyles.cssstyles.css
CSS
import * as React from "react";
import { Slider } from "radix-ui";
import "./styles.css";
const SliderDemo = () => (
<form>
<Slider.Root className="SliderRoot" defaultValue={[50]} max={100} step={1}>
<Slider.Track className="SliderTrack">
<Slider.Range className="SliderRange" />
</Slider.Track>
<Slider.Thumb className="SliderThumb" aria-label="Volume" />
</Slider.Root>
</form>
);
export default SliderDemo;
Can be controlled or uncontrolled.
Supports multiple thumbs.
Supports a minimum value between thumbs.
Supports touch or click on track to update value.
Supports Right to Left direction.
Full keyboard navigation.
Install the component from your command line.
npm install @radix-ui/react-slider
Import all parts and piece them together.
import { Slider } from "radix-ui";
export default () => (
<Slider.Root>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
</Slider.Root>
);
Contains all the parts of a slider. It will render an input for each thumb when used within a form to ensure events propagate correctly.
| Prop | Type | Default |
| --- | --- | --- |
| asChild<br><br>Prop description | boolean | false |
| defaultValue<br><br>Prop description | number[] | No default value |
| value<br><br>Prop description | number[] | No default value |
| onValueChange<br><br>Prop description | function<br><br>See full type | No default value |
| onValueCommit<br><br>Prop description | function<br><br>See full type | No default value |
| name<br><br>Prop description | string | No default value |
| disabled<br><br>Prop description | boolean | false |
| orientation<br><br>Prop description | enum<br><br>See full type | "horizontal" |
| dir<br><br>Prop description | enum<br><br>See full type | No default value |
| inverted<br><br>Prop description | boolean | false |
| min<br><br>Prop description | number | 0 |
| max<br><br>Prop description | number | 100 |
| step<br><br>Prop description | number | 1 |
| minStepsBetweenThumbs<br><br>Prop description | number | 0 |
| form<br><br>Prop description | string | No default value |
| Data attribute | Values |
| --- | --- |
| [data-disabled] | Present when disabled |
| [data-orientation] | "vertical" \| "horizontal" |
The track that contains the Slider.Range.
| Prop | Type | Default |
| --- | --- | --- |
| asChild<br><br>Prop description | boolean | false |
| Data attribute | Values |
| --- | --- |
| [data-disabled] | Present when disabled |
| [data-orientation] | "vertical" \| "horizontal" |
The range part. Must live inside Slider.Track.
| Prop | Type | Default |
| --- | --- | --- |
| asChild<br><br>Prop description | boolean | false |
| Data attribute | Values |
| --- | --- |
| [data-disabled] | Present when disabled |
| [data-orientation] | "vertical" \| "horizontal" |
A draggable thumb. You can render multiple thumbs.
| Prop | Type | Default |
| --- | --- | --- |
| asChild<br><br>Prop description | boolean | false |
| Data attribute | Values |
| --- | --- |
| [data-disabled] | Present when disabled |
| [data-orientation] | "vertical" \| "horizontal" |
Use the orientation prop to create a vertical slider.
// index.jsx
import { Slider } from "radix-ui";
import "./styles.css";
export default () => (
<Slider.Root
className="SliderRoot"
defaultValue={[50]}
orientation="vertical"
>
<Slider.Track className="SliderTrack">
<Slider.Range className="SliderRange" />
</Slider.Track>
<Slider.Thumb className="SliderThumb" />
</Slider.Root>
);
/* styles.css */
.SliderRoot {
position: relative;
display: flex;
align-items: center;
}
.SliderRoot[data-orientation="vertical"] {
flex-direction: column;
width: 20px;
height: 100px;
}
.SliderTrack {
position: relative;
flex-grow: 1;
background-color: grey;
}
.SliderTrack[data-orientation="vertical"] {
width: 3px;
}
.SliderRange {
position: absolute;
background-color: black;
}
.SliderRange[data-orientation="vertical"] {
width: 100%;
}
.SliderThumb {
display: block;
width: 20px;
height: 20px;
background-color: black;
}
Add multiple thumbs and values to create a range slider.
import { Slider } from "radix-ui";
export default () => (
<Slider.Root defaultValue={[25, 75]}>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
<Slider.Thumb />
</Slider.Root>
);
Use the step prop to increase the stepping interval.
import { Slider } from "radix-ui";
export default () => (
<Slider.Root defaultValue={[50]} step={10}>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
</Slider.Root>
);
Use minStepsBetweenThumbs to avoid thumbs with equal values.
import { Slider } from "radix-ui";
export default () => (
<Slider.Root defaultValue={[25, 75]} step={10} minStepsBetweenThumbs={1}>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
<Slider.Thumb />
</Slider.Root>
);
Adheres to the Slider WAI-ARIA design pattern .
| Key | Description |
| --- | --- |
| ArrowRight | Increments/decrements by the step value depending on orientation. |
| ArrowLeft | Increments/decrements by the step value depending on orientation. |
| ArrowUp | Increases the value by the step amount. |
| ArrowDown | Decreases the value by the step amount. |
| PageUp | Increases the value by a larger step. |
| PageDown | Decreases the value by a larger step. |
| Shift + ArrowUp | Increases the value by a larger step. |
| Shift + ArrowDown | Decreases the value by a larger step. |
| Home | Sets the value to its minimum. |
| End | Sets the value to its maximum. |
Create your own API by abstracting the primitive parts into your own component.
This example abstracts all of the Slider parts so it can be used as a self closing element.
import { Slider } from "./your-slider";
export default () => <Slider defaultValue={[25]} />;
// your-slider.jsx
import { Slider as SliderPrimitive } from "radix-ui";
export const Slider = React.forwardRef((props, forwardedRef) => {
const value = props.value || props.defaultValue;
return (
<SliderPrimitive.Slider {...props} ref={forwardedRef}>
<SliderPrimitive.Track>
<SliderPrimitive.Range />
</SliderPrimitive.Track>
{value.map((_, i) => (
<SliderPrimitive.Thumb key={i} />
))}
</SliderPrimitive.Slider>
);
});
Because of a limitation
we faced during implementation, the following example won't work as expected and the onMouseDown and onMouseUp event handlers won't be fired:
<Slider.Root
onMouseDown={() => console.log("onMouseDown")}
onMouseUp={() => console.log("onMouseUp")}
>
…
</Slider.Root>
We recommend using pointer events instead (eg. onPointerDown, onPointerUp). Regardless of the above limitation, these events are better suited for cross-platform/device handling as they are fired for all pointer input types (mouse, touch, pen, etc.).
PreviousSeparator
NextSwitch