Slider

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

Give FeedbackWAI-ARIABundle Size
50

Installation

Base UI components are all available as a single package.

npm install @base-ui-components/react

Once you have the package installed, import the component.

import { Slider } from '@base-ui-components/react/slider';

Anatomy

Sliders are implemented using a collection of related components:

<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:

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

Chrome versions below 124 does not implement aria-orientation correctly for vertical sliders (Chromium issue #40736841), and exposes them in the accessibility tree as horizontal.

The -webkit-appearance: slider-vertical CSS property can be used to correct this, though it will trigger a console warning in newer Chrome versions:

.MySlider-thumb > input {
  -webkit-appearance: slider-vertical;
}

The Slider.Thumb subcomponent automatically sets the CSS writing-mode property that fixes this bug for Chrome 124 and newer.

RTL

To change direction for right-to-left languages, place the slider in DirectionProvider with the direction="rtl" prop to configure RTL behavior, and set the dir attribute accordingly in your HTML to affect styling:

<html dir="rtl">
  <body>
    <DirectionProvider direction="rtl">
      <Slider.Root>{/* Subcomponents */}</Slider.Root>
    </DirectionProvider>
  </body>
</html>

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

50

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:

API Reference

SliderRoot

PropTypeDefaultDescription
aria-labelledbystringIdentifies the element (or elements) that labels the current element.
classNameunionClass names applied to the element or a function that returns them based on the component's state.
defaultValueunionThe default value of the slider. Use when the component is not controlled.
disabledboolfalseIf true, the component is disabled.
largeStepnumber10The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down.
maxnumber100The maximum allowed value of the slider. Should not be equal to min.
minnumber0The minimum allowed value of the slider. Should not be equal to max.
minStepsBetweenValuesnumber0The minimum steps between values in a range slider.
namestringName attribute of the hidden input element.
onValueChangefuncCallback function that is fired when the slider's value changed.
onValueCommittedfuncCallback function that is fired when the pointerup is triggered.
orientationenum'horizontal'The component orientation.
renderunionA function to customize rendering of the component.
stepnumber1The granularity with which the slider can step through values. (A "discrete" slider.) The min prop serves as the origin for the valid values. We recommend (max - min) to be evenly divisible by the step.
valueunionThe value of the slider. For ranged sliders, provide an array with two values.

SliderOutput

PropTypeDefaultDescription
classNameunionClass names applied to the element or a function that returns them based on the component's state.
renderunionA function to customize rendering of the component.

SliderControl

PropTypeDefaultDescription
classNameunionClass names applied to the element or a function that returns them based on the component's state.
renderunionA function to customize rendering of the component.

SliderTrack

PropTypeDefaultDescription
classNameunionClass names applied to the element or a function that returns them based on the component's state.
renderunionA function to customize rendering of the component.

SliderThumb

PropTypeDefaultDescription
aria-labelstringThe label for the input element.
aria-valuetextstringA string value that provides a user-friendly name for the current value of the slider.
classNameunionClass names applied to the element or a function that returns them based on the component's state.
getAriaLabelfuncAccepts a function which returns a string value that provides a user-friendly name for the input associated with the thumb
getAriaValueTextfuncAccepts a function which returns a string value that provides a user-friendly name for the current value of the slider. This is important for screen reader users.
renderunionA function to customize rendering of the component.

SliderIndicator

PropTypeDefaultDescription
classNameunionClass names applied to the element or a function that returns them based on the component's state.
renderunionA function to customize rendering of the component.

Contents