Skip to content

Slider (Range)

A UI input component where the user selects a value from within a given range. A Slider has a handle that can be moved along a track to change its value. When the user's mouse or focus is on the Slider's handle, the value can be incremented with keyboard controls.

Sliders are composed by an outer Slider component with a SliderTrack child component. SliderTrack can accept SliderRange, SliderMarker and SliderHandle components as children.

You can use Slider as a simple standalone component, or compose its parts with SliderInput.

function Example() {  return <Slider />;}
function Example() {  return (    <div>      <SliderInput>        <SliderTrack>          <SliderRange />          <SliderMarker value={50} />          <SliderHandle />        </SliderTrack>      </SliderInput>    </div>  );}


From the command line in your project directory, run npm install @reach/slider or yarn add @reach/slider. Then import the components and styles that you need:

npm install @reach/slider# oryarn add @reach/slider
import {  Slider,  SliderInput,  SliderTrack,  SliderRange,  SliderHandle,  SliderMarker,} from "@reach/slider";import "@reach/slider/styles.css";


// Basic sliderfunction Example() {  return <Slider min={0} max={200} step={10} />;}
// Composed slider componentsfunction ExampleComposed() {  return (    <SliderInput min={0} max={200} step={10}>      <SliderTrack>        <SliderRange />        <SliderHandle />      </SliderTrack>    </SliderInput>  );}

Slider Events

Prior to v0.10.0, Slider used pointer events for unified event handling across different pointer types (mouse, touch, stylus, etc.). While we still use onPointerUp and onPointerDown to take advantage of setPointerCapture and releasePointerCapture, we have moved all other logic to onMouseDown, onTouchStart, onMouseUp and onTouchEnd to prevent the need for a polyfill.

Another note on events: because the slider move and end events fire on the document (and because of some quirks in Chrome related to onTouchStart), the following event props on Slider and SliderInput use native DOM events rather than React's synthetic events in their respective handlers.

  • onPointerDown
  • onPointerUp
  • onMouseDown
  • onMouseMove
  • onMouseUp
  • onTouchStart
  • onTouchMove
  • onTouchEnd

Component API


High-level component to render a slider in its simplest form. This works simililarly to a native HTML range input.

<Slider min={0} max={100} />

Slider CSS Selectors

Please see the styling guide.

[data-reach-slider] {}[data-reach-slider][data-disabled] {}[data-reach-slider][data-orientation="(horizontal|vertical)"] {}

Slider Props

handleAlignment"center" | "contain"false"center"
orientation"horizontal" | "vertical"false"horizontal"
Slider children

children?: React.ReactNode

Slider can accept SliderMarker children to enhance display of specific values along the track.

<Slider min={0} max={100}>  {new Array(11).fill("x").map((x, index) => (    <SliderMarker value={index * 10}>      <span>{index * 10}</span>    </SliderMarker>  ))}</Slider>
Slider defaultValue

defaultValue?: number

The defaultValue is used to set an initial value for an uncontrolled Slider.

Slider disabled

disabled?: boolean

Whether or not the slider should be disabled from user interaction.

Slider getAriaLabel

getAriaLabel?(value: number): string

A function used to set a human-readable name for the slider.

Slider getAriaValueText

getAriaValueText?(value: number): string

A function used to set a human-readable value text based on the slider's current value.

Slider handleAlignment

handleAlignment?: "center" | "contain"

When set to center, the slider's handle will be positioned directly centered over the slider's curremt value on the track. This means that when the slider is at its min or max value, a visiable slider handle will extend beyond the width (or height in vertical mode) of the slider track. When set to contain, the slider handle will always be contained within the bounds of the track, meaning its position will be slightly offset from the actual value depending on where it sits on the track.

Slider max

max?: number

The maximum value of the slider. Defaults to 100.

Slider min

min?: number

The minimum value of the slider. Defaults to 0.

Slider name

name?: string

If the slider is used as a form input, it should accept a name prop to identify its value in context of the form.

Slider onChange

onChange?(newValue: number, props?: { min?: number, max?: number, handlePosition?: string }): void

Callback that fires when the slider value changes. When the value prop is set, the Slider state becomes controlled and onChange must be used to update the value in response to user interaction.

Slider orientation

orientation?: "horizontal" | "vertical"

Sets the slider to horizontal or vertical mode.

Slider step

step?: number

The step attribute is a number that specifies the granularity that the value must adhere to as it changes. Step sets minimum intervals of change, creating a "snap" effect when the handle is moved along the track.

Slider value

value?: number

An explicit value for the slider. When this prop is used, the Slider state becomes controlled and onChange must be used to update the value in response to user interaction.


The parent component of the slider interface. This is a lower level component if you need more control over styles or rendering the slider's inner components.

SliderInput CSS Selectors

See selectors for Slider.

SliderInput Props

SliderInput accepts the same props as Slider.

SliderInput children

children: React.ReactNode | ((props: { hasFocus?: boolean, id?: string | undefined, sliderId?: string | undefined, max?: number, min?: number, value?: number, valueText?: string | undefined }) => JSX.Element)

Slider expects <SliderTrack> as its child; The track will accept all additional slider sub-components as children. It can also accept a function/render prop as its child to expose some of its internal state variables.

SliderArgs = { hasFocus: boolean, id: string, max: number, min: number, value: number, valueText: string }


The parent component of the slider's inner components. Represents the visual track on which the slider's handle moves to represent its value.

SliderTrack CSS Selectors

Please see the styling guide.

[data-reach-slider-track] {}[data-reach-slider-track][data-disabled] {}[data-reach-slider-track][data-orientation="(horizontal|vertical)"] {}

SliderTrack Props

SliderTrack children

children: React.ReactNode

SliderTrack expects <SliderHandle>, at minimum, for the Slider to function. All other Slider subcomponents should be passed as children inside the SliderTrack.


The (typically) highlighted portion of the track that represents the space between the slider's min value and its current value.

NOTE: This component was named SliderTrackHighlight in a previous version of Reach UI. That component will be dropped in a future version. We recommend updating your projects to replace SliderTrackHighlight with SliderRange.

SliderRange CSS Selectors

Please see the styling guide.

[data-reach-slider-range] {}[data-reach-slider-range][data-disabled] {}[data-reach-slider-range][data-orientation="(horizontal|vertical)"] {}


A fixed value marker. These can be used to illustrate a range of steps or highlight important points along the slider track.

SliderMarker CSS Selectors

Please see the styling guide.

[data-reach-slider-marker] {}[data-reach-slider-marker][data-disabled] {}[data-reach-slider-marker][data-orientation="(horizontal|vertical)"] {}[data-reach-slider-marker][data-state="(under|at|over)-value"] {  /* marker is under, at, or over the slider value */}[data-reach-slider-marker][data-value="VALUE_REF"] {  /* marker is under, at, or over the slider value */}

SliderMarker Props

SliderMarker value

value: number

The value to denote where the marker should appear along the track.


The handle that the user drags along the track to set the slider value.

SliderHandle CSS Selectors

Please see the styling guide.

[data-reach-slider-handle] {}[data-reach-slider-handle][aria-disabled] {}[data-reach-slider-handle][aria-orientation="(horizontal|vertical)"] {}