Range Slider
A control element that allows for a range of selections.
A control element that allows for a range of selections.
To set up the slider correctly, you’ll need to understand its anatomy and how we name its parts.
Each part includes a
data-partattribute to help identify them in the DOM.
You can use the Slider component as a range slider by setting the value with
an array of two numbers.
The first number is the start of the range, and the second number is the end of the range.
import { Slider } from '@ark-ui/react'
const Basic = () => {
  return (
    <Slider.Root defaultValue={[5, 10]}>
      <Slider.Label>Label</Slider.Label>
      <Slider.ValueText />
      <Slider.Control>
        <Slider.Track>
          <Slider.Range />
        </Slider.Track>
        <Slider.Thumb key={0} index={0} />
        <Slider.Thumb key={1} index={1} />
      </Slider.Control>
    </Slider.Root>
  )
}
import { Slider } from '@ark-ui/solid'
const Basic = () => {
  return (
    <Slider.Root value={[5, 10]}>
      <Slider.Label>Label</Slider.Label>
      <Slider.ValueText />
      <Slider.Control>
        <Slider.Track>
          <Slider.Range />
        </Slider.Track>
        <Slider.Thumb index={0} />
        <Slider.Thumb index={1} />
      </Slider.Control>
    </Slider.Root>
  )
}
<script setup lang="ts">
import { Slider } from '@ark-ui/vue'
</script>
<template>
  <Slider.Root :model-value="[5, 10]">
    <Slider.Label>Label</Slider.Label>
    <Slider.ValueText />
    <Slider.Control>
      <Slider.Track>
        <Slider.Range />
      </Slider.Track>
      <Slider.Thumb :key="0" :index="0" />
      <Slider.Thumb :key="1" :index="1" />
    </Slider.Control>
  </Slider.Root>
</template>
You can add marks to the slider track by using the Slider.MarkerGroup and
Slider.Marker components.
Position the Slider.Marker components relative to the track by providing the
value prop.
import { Slider } from '@ark-ui/react'
const WithMarks = () => {
  return (
    <Slider.Root defaultValue={[10, 60]}>
      <Slider.Label>Label</Slider.Label>
      <Slider.ValueText />
      <Slider.Control>
        <Slider.Track>
          <Slider.Range />
        </Slider.Track>
        <Slider.Thumb key={0} index={0} />
        <Slider.Thumb key={1} index={1} />
      </Slider.Control>
      <Slider.MarkerGroup>
        <Slider.Marker value={0}>0</Slider.Marker>
        <Slider.Marker value={25}>*</Slider.Marker>
        <Slider.Marker value={50}>50</Slider.Marker>
        <Slider.Marker value={75}>*</Slider.Marker>
      </Slider.MarkerGroup>
    </Slider.Root>
  )
}
import { Slider } from '@ark-ui/solid'
const WithMarks = () => {
  return (
    <Slider.Root value={[10, 60]}>
      <Slider.Label>Label</Slider.Label>
      <Slider.ValueText />
      <Slider.Control>
        <Slider.Track>
          <Slider.Range />
        </Slider.Track>
        <Slider.Thumb index={0} />
        <Slider.Thumb index={1} />
      </Slider.Control>
      <Slider.MarkerGroup>
        <Slider.Marker value={0}>0</Slider.Marker>
        <Slider.Marker value={25}>*</Slider.Marker>
        <Slider.Marker value={50}>50</Slider.Marker>
        <Slider.Marker value={75}>*</Slider.Marker>
      </Slider.MarkerGroup>
    </Slider.Root>
  )
}
<script setup lang="ts">
import { Slider } from '@ark-ui/vue'
</script>
<template>
  <Slider.Root :model-value="[10, 60]">
    <Slider.Label>Label</Slider.Label>
    <Slider.ValueText />
    <Slider.Control>
      <Slider.Track>
        <Slider.Range />
      </Slider.Track>
      <Slider.Thumb :key="0" :index="0" />
      <Slider.Thumb :key="1" :index="1" />
    </Slider.Control>
    <Slider.MarkerGroup>
      <Slider.Marker :value="0">0</Slider.Marker>
      <Slider.Marker :value="25">*</Slider.Marker>
      <Slider.Marker :value="50">50</Slider.Marker>
      <Slider.Marker :value="75">*</Slider.Marker>
    </Slider.MarkerGroup>
  </Slider.Root>
</template>
To set the slider’s initial value, set the defaultValue prop to the array of
numbers.
import { Slider } from '@ark-ui/react'
const InitialValue = () => (
  <Slider.Root defaultValue={[9, 42]}>
    <Slider.Label>Label</Slider.Label>
    <Slider.ValueText />
    <Slider.Control>
      <Slider.Track>
        <Slider.Range />
      </Slider.Track>
      <Slider.Thumb key={0} index={0} />
      <Slider.Thumb key={1} index={1} />
    </Slider.Control>
    <Slider.MarkerGroup>
      <Slider.Marker value={0}>*</Slider.Marker>
      <Slider.Marker value={30}>*</Slider.Marker>
      <Slider.Marker value={60}>*</Slider.Marker>
    </Slider.MarkerGroup>
  </Slider.Root>
)
import { Slider } from '@ark-ui/solid'
const InitialValue = () => (
  <Slider.Root value={[9, 42]}>
    <Slider.Label>Label</Slider.Label>
    <Slider.ValueText />
    <Slider.Control>
      <Slider.Track>
        <Slider.Range />
      </Slider.Track>
      <Slider.Thumb index={0} />
      <Slider.Thumb index={1} />
    </Slider.Control>
    <Slider.MarkerGroup>
      <Slider.Marker value={0}>*</Slider.Marker>
      <Slider.Marker value={30}>*</Slider.Marker>
      <Slider.Marker value={60}>*</Slider.Marker>
    </Slider.MarkerGroup>
  </Slider.Root>
)
<script setup lang="ts">
import { Slider } from '@ark-ui/vue'
</script>
<template>
  <Slider.Root :model-value="[9, 42]">
    <Slider.Label>Label</Slider.Label>
    <Slider.ValueText />
    <Slider.Control>
      <Slider.Track>
        <Slider.Range />
      </Slider.Track>
      <Slider.Thumb :key="0" :index="0" />
      <Slider.Thumb :key="1" :index="1" />
    </Slider.Control>
    <Slider.MarkerGroup>
      <Slider.Marker :value="0">*</Slider.Marker>
      <Slider.Marker :value="30">*</Slider.Marker>
      <Slider.Marker :value="60">*</Slider.Marker>
    </Slider.MarkerGroup>
  </Slider.Root>
</template>
By default, the minimum is 0 and the maximum is 100. If that’s not what you
want, you can easily specify different bounds by changing the values of the
min and/or max props.
For example, to ask the user for a value between -10 and 10, you can use:
import { Slider } from '@ark-ui/react'
const MinMax = () => {
  return (
    <Slider.Root min={-10} max={10} defaultValue={[-5, 5]}>
      <Slider.Label>Label</Slider.Label>
      <Slider.ValueText />
      <Slider.Control>
        <Slider.Track>
          <Slider.Range />
        </Slider.Track>
        <Slider.Thumb key={0} index={0} />
        <Slider.Thumb key={1} index={1} />
      </Slider.Control>
    </Slider.Root>
  )
}
import { Slider } from '@ark-ui/solid'
const MinMax = () => {
  return (
    <Slider.Root min={-10} max={10} value={[-5, 5]}>
      <Slider.Label>Label</Slider.Label>
      <Slider.ValueText />
      <Slider.Control>
        <Slider.Track>
          <Slider.Range />
        </Slider.Track>
        <Slider.Thumb index={0} />
        <Slider.Thumb index={1} />
      </Slider.Control>
    </Slider.Root>
  )
}
<script setup lang="ts">
import { Slider } from '@ark-ui/vue'
</script>
<template>
  <Slider.Root :min="-10" :max="10" :model-value="[-5, 5]">
    <Slider.Label>Label</Slider.Label>
    <Slider.ValueText />
    <Slider.Control>
      <Slider.Track>
        <Slider.Range />
      </Slider.Track>
      <Slider.Thumb :key="0" :index="0" />
      <Slider.Thumb :key="1" :index="1" />
    </Slider.Control>
  </Slider.Root>
</template>
By default, the granularity, is 1, meaning that the value is always an
integer. You can change the step attribute to control the granularity.
For example, If you need a value between 5 and 10, accurate to two decimal
places, you should set the value of step to 0.01:
import { Slider } from '@ark-ui/react'
const Step = () => {
  return (
    <Slider.Root step={0.01} min={5} max={10} defaultValue={[7.5, 8]}>
      <Slider.Label>Label</Slider.Label>
      <Slider.ValueText />
      <Slider.Control>
        <Slider.Track>
          <Slider.Range />
        </Slider.Track>
        <Slider.Thumb key={0} index={0} />
        <Slider.Thumb key={1} index={1} />
      </Slider.Control>
    </Slider.Root>
  )
}
import { Slider } from '@ark-ui/solid'
const Step = () => {
  return (
    <Slider.Root step={0.01} min={5} max={10} value={[7.5, 8]}>
      <Slider.Label>Label</Slider.Label>
      <Slider.ValueText />
      <Slider.Control>
        <Slider.Track>
          <Slider.Range />
        </Slider.Track>
        <Slider.Thumb index={0} />
        <Slider.Thumb index={1} />
      </Slider.Control>
    </Slider.Root>
  )
}
<script setup lang="ts">
import { Slider } from '@ark-ui/vue'
</script>
<template>
  <Slider.Root :step="0.01" :min="5" :max="10" :model-value="[7.5, 8]">
    <Slider.Label>Label</Slider.Label>
    <Slider.ValueText />
    <Slider.Control>
      <Slider.Track>
        <Slider.Range />
      </Slider.Track>
      <Slider.Thumb :key="0" :index="0" />
      <Slider.Thumb :key="1" :index="1" />
    </Slider.Control>
  </Slider.Root>
</template>
When the slider value changes, the onValueChange and onValueChangeEnd
callbacks are invoked. You can use this to set up custom behaviors in your app.
import { Slider } from '@ark-ui/react'
const OnEvent = () => {
  return (
    <Slider.Root
      defaultValue={[5, 10]}
      onValueChange={(details) => console.log(details.value)}
      onValueChangeEnd={(details) => console.log(details.value)}
    >
      <Slider.Label>Label</Slider.Label>
      <Slider.ValueText />
      <Slider.Control>
        <Slider.Track>
          <Slider.Range />
        </Slider.Track>
        <Slider.Thumb key={0} index={0} />
        <Slider.Thumb key={1} index={1} />
      </Slider.Control>
    </Slider.Root>
  )
}
import { Slider } from '@ark-ui/solid'
const OnEvent = () => {
  return (
    <Slider.Root
      value={[5, 10]}
      onValueChange={(details) => console.log(details.value)}
      onValueChangeEnd={(details) => console.log(details.value)}
    >
      <Slider.Label>Label</Slider.Label>
      <Slider.ValueText />
      <Slider.Control>
        <Slider.Track>
          <Slider.Range />
        </Slider.Track>
        <Slider.Thumb index={0} />
        <Slider.Thumb index={1} />
      </Slider.Control>
    </Slider.Root>
  )
}
<script setup lang="ts">
import { Slider } from '@ark-ui/vue'
</script>
<template>
  <Slider.Root
    :model-value="[5, 10]"
    @value-change="(details) => console.log(details.value)"
    @value-change-end="(details) => console.log(details.value)"
  >
    <Slider.Label>Label</Slider.Label>
    <Slider.ValueText />
    <Slider.Control>
      <Slider.Track>
        <Slider.Range />
      </Slider.Track>
      <Slider.Thumb :key="0" :index="0" />
      <Slider.Thumb :key="1" :index="1" />
    </Slider.Control>
  </Slider.Root>
</template>
By default, the slider is assumed to be horizontal. To change the orientation to vertical, set the orientation property in the machine’s context to vertical.
In this mode, the slider will use the arrow up and down keys to increment/decrement its value.
Don’t forget to change the styles of the vertical slider by specifying its height
import { Slider } from '@ark-ui/react'
const Vertical = () => {
  return (
    <Slider.Root orientation="vertical" defaultValue={[5, 60]}>
      <Slider.Label>Label</Slider.Label>
      <Slider.ValueText />
      <Slider.Control>
        <Slider.Track>
          <Slider.Range />
        </Slider.Track>
        <Slider.Thumb key={0} index={0} />
        <Slider.Thumb key={1} index={1} />
      </Slider.Control>
    </Slider.Root>
  )
}
import { Slider } from '@ark-ui/solid'
const Vertical = () => {
  return (
    <Slider.Root orientation="vertical" value={[5, 60]}>
      <Slider.Label>Label</Slider.Label>
      <Slider.ValueText />
      <Slider.Control>
        <Slider.Track>
          <Slider.Range />
        </Slider.Track>
        <Slider.Thumb index={0} />
        <Slider.Thumb index={1} />
      </Slider.Control>
    </Slider.Root>
  )
}
<script setup lang="ts">
import { Slider } from '@ark-ui/vue'
</script>
<template>
  <Slider.Root orientation="vertical" :model-value="[5, 60]">
    <Slider.Label>Label</Slider.Label>
    <Slider.ValueText />
    <Slider.Control>
      <Slider.Track>
        <Slider.Range />
      </Slider.Track>
      <Slider.Thumb :key="0" :index="0" />
      <Slider.Thumb :key="1" :index="1" />
    </Slider.Control>
  </Slider.Root>
</template>
By default, the range slider thumbs are allowed to overlap when their values are
equal. To prevent this, use the minStepsBetweenThumbs to avoid thumbs with
equal values.
import { Slider } from '@ark-ui/react'
const ThumbOverlap = () => {
  return (
    <Slider.Root minStepsBetweenThumbs={1} defaultValue={[5, 60]}>
      <Slider.Label>Label</Slider.Label>
      <Slider.ValueText />
      <Slider.Control>
        <Slider.Track>
          <Slider.Range />
        </Slider.Track>
        <Slider.Thumb key={0} index={0} />
        <Slider.Thumb key={1} index={1} />
      </Slider.Control>
    </Slider.Root>
  )
}
import { Slider } from '@ark-ui/solid'
const ThumbOverlap = () => {
  return (
    <Slider.Root minStepsBetweenThumbs={1} value={[5, 60]}>
      <Slider.Label>Label</Slider.Label>
      <Slider.ValueText />
      <Slider.Control>
        <Slider.Track>
          <Slider.Range />
        </Slider.Track>
        <Slider.Thumb index={0} />
        <Slider.Thumb index={1} />
      </Slider.Control>
    </Slider.Root>
  )
}
<script setup lang="ts">
import { Slider } from '@ark-ui/vue'
</script>
<template>
  <Slider.Root :minStepsBetweenThumbs="1" :model-value="[5, 60]">
    <Slider.Label>Label</Slider.Label>
    <Slider.ValueText />
    <Slider.Control>
      <Slider.Track>
        <Slider.Range />
      </Slider.Track>
      <Slider.Thumb :key="0" :index="0" />
      <Slider.Thumb :key="1" :index="1" />
    </Slider.Control>
  </Slider.Root>
</template>
| Prop | Type | Default | 
|---|---|---|
| aria-labelThe aria-label of each slider thumb. Useful for providing an accessible name to the slider | string[] | |
| aria-labelledbyThe `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | string[] | |
| asChildRender as a different element type. | boolean | |
| defaultValueThe initial value of the slider slider. | number[] | |
| dirThe document's text/writing direction. | 'ltr' | 'rtl' | "ltr" | 
| disabledWhether the slider is disabled | boolean | |
| formThe associate form of the underlying input element. | string | |
| getAriaValueTextFunction that returns a human readable value for the slider thumb | (value: number, index: number) => string | |
| getRootNodeA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | () => Node | ShadowRoot | Document | |
| idThe unique identifier of the machine. | string | |
| idsThe ids of the elements in the range slider. Useful for composition. | Partial<{
  root: string
  thumb(index: number): string
  control: string
  track: string
  range: string
  label: string
  valueText: string
  marker(index: number): string
}> | |
| invalidWhether the slider is invalid | boolean | |
| maxThe maximum value of the slider | number | |
| minThe minimum value of the slider | number | |
| minStepsBetweenThumbsThe minimum permitted steps between multiple thumbs. | number | |
| nameThe name associated with each slider thumb (when used in a form) | string | |
| onFocusChangeFunction invoked when the slider's focused index changes | (details: FocusChangeDetails) => void | |
| onValueChangeFunction invoked when the value of the slider changes | (details: ValueChangeDetails) => void | |
| onValueChangeEndFunction invoked when the slider value change is done | (details: ValueChangeDetails) => void | |
| orientationThe orientation of the slider | 'horizontal' | 'vertical' | |
| origin- "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) | 'center' | 'start' | |
| readOnlyWhether the slider is read-only | boolean | |
| stepThe step value of the slider | number | |
| thumbAlignmentThe alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | 'center' | 'contain' | |
| thumbSizeThe slider thumbs dimensions | { width: number; height: number } | |
| valueThe value of the range slider | number[] | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| index | number | |
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| value | number | |
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
Previous
Radio GroupNext
Rating Group