Skip to content
+

Slider

The Slider component provides users with an input for a one or more numerical values within a given range.

50

Installation

Base UI components are all available as a single package.

npm install @base_ui/react

Once you have the package installed, import the component.

import * as Slider from '@base_ui/react/Slider';

Anatomy

Sliders are implemented using a collection of related components:

  • <Slider.Root /> is a top-level component that wraps the other components.
  • <Slider.Output /> renders the value of the slider.
  • <Slider.Control /> renders the click/touch area that contains the track and thumb.
  • <Slider.Track /> renders the visible rail on the Control along which the thumb(s) can be moved.
  • <Slider.Indicator /> renders the filled portion of the track which represents the value(s).
  • <Slider.Thumb /> renders the element that can be moved along the track to change the value.
<Slider.Root>
  <Slider.Output />
  <Slider.Control>
    <Slider.Track>
      <Slider.Indicator />
      <Slider.Thumb />
    <Slider.Track/>
  </Slider.Control>
</Slider.Root>

Value

Default value

When Slider is uncontrolled, the defaultValue prop sets the initial value of the component.

function App() {
  return (
    <Slider.Root defaultValue={50}>
      <Slider.Output />
      <Slider.Control>
        <Slider.Track>
          <Slider.Indicator />
          <Slider.Thumb />
        <Slider.Track/>
      </Slider.Control>
    </Slider.Root>
  );
}

Controlled

When Slider is uncontrolled, the value prop holds the numerical value(s), and two callbacks are provided for when the value changes:

  • onValueChange is called when the value is changing while the thumb is being moved along the control area
  • onValueCommitted is called when thumb stops moving and either pointerup or keydown are triggered
function App() {
  const [value, setValue] = useState(50);
  return (
    <Slider.Root value={value} onValueChange={setValue}>
      <Slider.Output />
      <Slider.Control>
        <Slider.Track>
          <Slider.Indicator />
          <Slider.Thumb />
        <Slider.Track/>
      </Slider.Control>
    </Slider.Root>
  );
}

Validation

Min and max

The min and max props can be used to restrict the value(s) within a range.

<Slider.Root min={1} max={9}>
  <Slider.Output />
  <Slider.Control>
    <Slider.Track>
      <Slider.Indicator />
      <Slider.Thumb />
    <Slider.Track/>
  </Slider.Control>
</Slider.Root>

Step

The step prop snaps each value to multiples of the given number. In the below example, the input value snaps to increments of 4 starting from the initial defaultValue: 3, 7, 11, 15, and so on.

<Slider.Root step={4} defaultValue={3}>
  <Slider.Output />
  <Slider.Control>
    <Slider.Track>
      <Slider.Indicator />
      <Slider.Thumb />
    <Slider.Track/>
  </Slider.Control>
</Slider.Root>

You can specify the largeStep prop to change the step when the user holds the shift key, snapping to multiples of 10 by default.

Range Sliders

To let users set the start and end of a range on a Slider, provide an array of values to the value or defaultValue prop, and place a <Slider.Thumb /> for each value in the array:

<Slider.Root defaultValue={[45, 70]}>
  <Slider.Output />
  <Slider.Control>
    <Slider.Track>
      <Slider.Indicator />
      <Slider.Thumb />
      <Slider.Thumb />
    <Slider.Track/>
  </Slider.Control>
</Slider.Root>
Controlled Range20 – 37
Uncontrolled Range20 – 37

Overlapping values

The minStepsBetweenValues prop can be used to to set the mininum number of steps between values in a range slider, so thumbs do not overlap in the same position:

<Slider.Root minStepsBetweenValues={2} step={5} defaultValue={[10, 20]}>
  <Slider.Control>
    <Slider.Track>
      <Slider.Indicator />
      <Slider.Thumb />
      <Slider.Thumb />
    <Slider.Track/>
  </Slider.Control>
</Slider.Root>

Vertical

To create vertical sliders, set the orientation prop to "vertical". This will track thumb movements vertically instead of horizontally.

<Slider.Root orientation="vertical">{/* Subcomponents */}</Slider.Root>
50

RTL

Set the direction prop to 'rtl' to change the slider's direction for right-to-left languages:

<Slider.Root direction="rtl">{/* Subcomponents */}</Slider.Root>

In a RTL Slider, Left Arrow increases the value while Right Arrow decreases the value.

50
Press Enter to start editing

Overriding default components

Use the render prop to override the rendered elements with your own components.

<Slider.Control render={(props) => <MyCustomTrack {...props} />}> />

All subcomponents accept the render prop.

The Slider.Thumb component's render prop contains an additional inputProps argument for rendering an input element attached to the thumb:

<Slider.Thumb
  render={(props, inputProps) => {
    const { children, ...other } = props;
    return (
      <MyCustomThumb {...other}>
        {children}
        <input {...inputProps}>
      <MyCustomThumb/>
    )
  }}>
/>

It's handled automatically if you use the shorthand:

<Slider.Thumb render={<MyCustomThumb />} />

Accessibility

See the WAI-ARIA guide on the Slider (Multi-Thumb) pattern for complete details on accessibility best practices.

The component handles most of the work necessary to make it accessible. However, you need to make sure that:

  • Each thumb has a user-friendly label (aria-label, aria-labelledby or getAriaLabel prop).
  • Each thumb has a user-friendly text for its current value. This is not required if the value matches the semantics of the label. You can change the name with the getAriaValueText or aria-valuetext prop.