Skip to content

Slider

InputsSince 0.9.0
import { Slider } from '@absoluteui/components/slider';
import '@absoluteui/components/slider/style.css';

Using Angular? See Slider for Angular.

Picks a number, or a range with two thumbs, from a bounded scale such as volume, a price range, or working hours. Each thumb is a WAI-ARIA slider; range thumbs limit each other (APG multi-thumb slider). The keyboard moves by step, large step, or to the ends, and the pointer can press anywhere on the track and drag. Slider is a Form control: it validates, serializes, and resets with Form, and native forms receive hidden inputs.

  • Approximate values where the position on a scale matters more than the exact number: volume, opacity, rating thresholds.
  • A range filter such as a price or a working-hours window.
  • Exact numbers the user types: use Number Input.
  • Scales with more than a few hundred steps where precision matters (pair the slider with a Number Input or use one).
  • Choosing among named options: use Radio Group or Toggle Group.
import { Slider } from '@absoluteui/components/slider';
const host = document.createElement('div');
document.body.append(host);
Slider.create(host, {
label: 'Volume',
value: 40,
step: 10,
marks: true,
valueText: (v) => `${String(v)}%`,
});
import { Slider, type SliderValueDetail } from '@absoluteui/components/slider';
const host = document.createElement('div');
const summary = document.createElement('p');
document.body.append(host, summary);
Slider.create(host, {
label: 'Price',
range: true,
min: 0,
max: 500,
step: 10,
value: [50, 300],
format: { style: 'currency', currency: 'EUR', maximumFractionDigits: 0 },
marks: [{ value: 0, label: 'Free' }, { value: 500, label: 'Max' }],
});
host.addEventListener('aui-change', (event) => {
const { value } = (event as CustomEvent<SliderValueDetail>).detail;
if (Array.isArray(value)) summary.textContent = `Searching ${String(value[0])} to ${String(value[1])} EUR`;
});
import { formatPlainTime, plainTime } from '@absoluteui/core';
import { Slider } from '@absoluteui/components/slider';
const host = document.createElement('div');
document.body.append(host);
// Minutes since midnight, shown as times of day.
Slider.create(host, {
label: 'Working hours',
range: true,
min: 0,
max: 23 * 60 + 30,
step: 30,
value: [9 * 60, 17 * 60],
largeStep: 120,
valueText: (m) => formatPlainTime(plainTime(Math.floor(m / 60), m % 60), { timeStyle: 'short' }),
});
import { Slider } from '@absoluteui/components/slider';
import '@absoluteui/components/slider/style.css';
const host = document.querySelector<HTMLElement>('#rating');
if (host) Slider.create(host, { label: 'Minimum rating', min: 1, max: 5, value: 3, marks: true, valueText: (v) => `${String(v)} stars` });
import { Slider, type SliderValueDetail } from '@absoluteui/components/slider';
const host = document.querySelector<HTMLElement>('#opacity');
if (host) {
Slider.create(host, { label: 'Opacity', min: 0, max: 1, step: 0.05, value: 0.8, format: { style: 'percent' } });
host.addEventListener('aui-input', (event) => {
const { value } = (event as CustomEvent<SliderValueDetail>).detail;
if (typeof value === 'number') document.documentElement.style.setProperty('--preview-opacity', String(value));
});
}
<div class="aui-field aui-slider [--range] [--vertical]">
<div class="aui-slider__header"><label class="aui-field__label">Price</label><span class="aui-slider__output" aria-hidden="true">€50 to €300</span></div>
<div class="aui-field__description">help</div>
<div class="aui-slider__control">
<div class="aui-slider__track"><div class="aui-slider__fill"></div></div>
<div class="aui-slider__thumb" role="slider" tabindex="0" aria-valuenow aria-valuemin aria-valuemax aria-valuetext aria-labelledby></div> (x2 for range)
</div>
<div class="aui-slider__marks" aria-hidden="true">ticks and labels</div>
<div class="aui-field__error">error</div>
<input type="hidden" name="price"> (x2 for range)
</div>
Slider.create(host: HTMLElement, options: SliderOptions): Slider

Global configuration key: slider (see Configuration).

Option Type Default Description
label string Visible label; names the thumbs. Required.
hideLabel boolean "false" Visually hide the label.
description string Help text, referenced by the thumbs.
min number "0" Lower bound.
max number "100" Upper bound (greater than min).
step number "1" Values snap to min + n * step.
largeStep number Page Up/Page Down step (default: a tenth of the scale in whole steps).
value SliderValue A number, or [start, end] with range.
range boolean "false" Two thumbs selecting [start, end].
orientation 'horizontal' | 'vertical' "horizontal" Layout and key mapping.
marks boolean | readonly SliderMark[] true: a tick per step (up to 100); or explicit { value, label? } marks.
format Intl.NumberFormatOptions Number format of the value text.
valueText (value: number) => string Full value text (overrides format).
disabled boolean "false" Disable the slider.
name string Form field name (hidden inputs; a range submits two values).
showValue boolean "true" Show the value next to the label. Globally configurable.
locale string "en-US" Locale of the value text and thumb names. Globally configurable. Inherited from common configuration.
Property Type Description
host HTMLElement The host element.
value SliderValue A number, or [start, end] with range.
validity ControlValidity Valid unless a custom error is set.
options Readonly<SliderOptions> Current options.
Method Description
setValue(value: SliderValue): void Set the value, snapped and clamped (no event).
setCustomError(message: string | null): void Show or clear an external error.
focus(): void Focus the (first) thumb.
reset(): void Restore the initial value and clear the error.
update(options: Partial<SliderOptions>): void Merge and apply options; the value is re-snapped.
destroy(): void Remove rendering, listeners, and the form registration.
Event Detail Bubbles Cancelable Description
aui-input SliderValueDetail Yes No The value changes while dragging or with a key: { value }.
aui-change SliderValueDetail Yes No The value was committed (pointer release or a key): { value }.

All rules live in the aui.components cascade layer, so application styles override them without specificity battles.

Class Purpose
aui-slider Host (with aui-field).
aui-slider--range | --vertical | --disabled | --invalid State modifiers.
aui-slider__header Label and value text.
aui-slider__output Visible value text (aria-hidden).
aui-slider__control Pointer area.
aui-slider__track Track.
aui-slider__fill Filled part of the track.
aui-slider__thumb A thumb (role=slider).
aui-slider__marks Tick marks (aria-hidden).
aui-slider__mark | __mark--active | __mark-label A tick, an active tick, and its label.

Tokens this stylesheet reads (verified in CI). Override them in a theme or with the Theme Designer.

--aui-color-border-strong | --aui-color-error-fg | --aui-color-focus-ring | --aui-color-primary | --aui-color-surface | --aui-color-text | --aui-color-text-disabled | --aui-color-text-muted | --aui-duration-fast | --aui-easing-standard | --aui-focus-ring-offset | --aui-focus-ring-width | --aui-font-family-sans | --aui-font-size-sm | --aui-font-size-xs | --aui-font-weight-medium | --aui-icon-size-sm | --aui-line-height-tight | --aui-radius-pill | --aui-shadow-sm | --aui-space-1 | --aui-space-2 | --aui-touch-target-min

type SliderValue = number | readonly [number, number];
interface SliderConfig { showValue: boolean }
interface SliderMark { value: number; label?: string }
interface SliderOptions extends Partial<SliderConfig> {
label: string;
hideLabel?: boolean;
description?: string;
min?: number;
max?: number;
step?: number;
largeStep?: number;
value?: SliderValue;
range?: boolean;
orientation?: 'horizontal' | 'vertical';
marks?: boolean | readonly SliderMark[];
format?: Intl.NumberFormatOptions;
valueText?: (value: number) => string;
disabled?: boolean;
name?: string;
locale?: string;
}
interface SliderValueDetail { value: SliderValue }

Pattern: WAI-ARIA APG Slider and Multi-Thumb Slider: each thumb is role=slider with aria-valuenow, aria-valuemin, aria-valuemax, and aria-valuetext.

Key Context Action
ArrowRight / ArrowUp Thumb Increase by one step (ArrowLeft increases in right-to-left).
ArrowLeft / ArrowDown Thumb Decrease by one step (ArrowRight decreases in right-to-left).
Page Up / Page Down Thumb Increase or decrease by the large step.
Home / End Thumb Set to the minimum or maximum (within the other thumb’s limit for range).
Tab Range Moves between the two thumbs.
Element Role
thumb slider
marks and visible value none (aria-hidden; the thumbs announce values)
Attribute Element Value
aria-labelledby thumb the label, plus ‘Minimum’ or ‘Maximum’ for range thumbs
aria-valuemin / aria-valuemax thumb bounds; range thumbs are limited by the other thumb
aria-valuenow / aria-valuetext thumb the value and its formatted text
aria-orientation thumb vertical when vertical
aria-describedby thumb help text and error
aria-invalid thumb true with a custom error
aria-disabled thumb true when disabled (also removed from the tab order)

Each thumb is in the tab sequence; pressing the track focuses the moved thumb.

Criterion Level Note
1.3.1 Info and Relationships A
1.4.11 Non-text Contrast AA
2.1.1 Keyboard A
2.5.7 Dragging Movements AA
4.1.2 Name, Role, Value A

Automated test results: Accessibility and compliance.

  • Dragging has a single-pointer alternative (press on the track) and a keyboard alternative (WCAG 2.5.7).
  • Value text uses valueText or the number format, so screen readers hear ‘€20’, ‘3 stars’, or ‘09:00’ rather than raw numbers.
  • Manual screen-reader verification (NVDA, JAWS, VoiceOver) is pending.

Single or range; horizontal or vertical; marks; value shown; disabled; invalid (custom error); dragging.

From Trigger To
any arrow, Page, Home, or End key new value; aui-input and aui-change
any press on the track the nearer thumb jumps there and follows the pointer; aui-input
dragging release aui-change when the value changed
dragging pointer cancel the value before the drag
range a thumb reaches the other it stops there (thumbs never cross)
  • Dragging has single-pointer (press on the track) and keyboard alternatives (WCAG 2.5.7).
  • Give a meaningful valueText or format so screen readers hear “€20” or “09:00”, not a raw number.
  • The e2e axe run covers three themes; manual screen-reader verification is pending.

Horizontal sliders fill their container; vertical sliders are 12rem tall. The thumbs never overflow the field.

Horizontal sliders run right to left: the minimum is at the right and ArrowLeft increases.

The fill, track, and focus colors are in the contrast gate. Forced colors use Highlight for the fill and thumbs and GrayText for the track.

configureAbsoluteUI({ components: { slider: { showValue: false } } });

Instance showValue and locale override configuration; configuration changes re-render existing sliders.

Not applicable. For times of day, use minutes as the scale and format them with valueText (see the working-hours example).

Labels and value text use textContent. Thumb positions are set through the CSSOM, so a strict CSP without unsafe-inline styles works.

No persistence, network access, or telemetry.

Each move updates attributes and two CSS custom properties; marks are re-rendered with the value (at most 100).

Any finite min, max, and step; tick marks are limited to 100 (otherwise only the ends are marked).

  • When max is not on the step grid, the highest reachable value below max is the last whole step; max itself is reachable with End.
  • update({ min, max, step }) re-snaps the current value.
  • setValue([70, 10]) is reordered to [10, 70].
  • A pointer cancel (for example a scroll gesture taking over) restores the value from before the drag.
Code Category Cause
SLIDER_OPTIONS configuration Blank label, min >= max, a non-positive or too large step, a value of the wrong shape for range, an unknown orientation, invalid marks, or a non-function valueText.
CFG_INVALID_VALUE / CFG_UNKNOWN_OPTION configuration Invalid configuration.

Invalid options throw before the host is modified; an invalid update() leaves the previous state intact.

  • Vertical sliders hide marks.
  • Manual screen-reader verification is pending.
  • More than two thumbs.
  • Non-linear scales: map values yourself and show them with valueText.