Components
Slider
A styled, accessible native range input.
The slider is a restyled native <input type="range">. Accessible and keyboard-operable.
Use the standard min, max, step, and value attributes.
Default
Loading components…
<input class="max-w-xl" type="range" min="0" max="100" step="10" value="50" aria-label="Volume" />/** * _slider.css — Range input (input[type="range"]) * * @layer reset * @requires layers.css, _variables.css * @uses appearance: none — redraws track + thumb from theme tokens * @tokens --range-* (track height, background, border, radius; thumb size, bg, border, radius) * * Note: The active region is NOT filled (parity across engines); add a paint * via JS if a filled track is needed. The thumb is centered on the track with a * calc'd negative margin so retuning either size keeps it aligned. */@layer reset { :where(input[type="range"]) { --range-ring-color: var(--ring-color); --range-track-height: var(--step-1_5); --range-track-background: var(--muted); --range-track-border: 1px solid var(--muted); --range-track-radius: var(--radius-full); --range-thumb-size: var(--step-4); --range-thumb-background: var(--background); --range-thumb-shadow: var(--shadow-xs); --range-thumb-border: 1px solid var(--border); --range-thumb-radius: var(--radius-full); --range-thumb-offset: calc(var(--range-track-height) * -1); -webkit-appearance: none; appearance: none; inline-size: 100%; background: transparent; cursor: grab; border-radius: var(--range-track-radius); /* transparent outline keeps focus visible in forced-colors / high-contrast modes; the visible focus ring lives on the thumb via --shadow-ring */ outline: var(--outline-width) var(--outline-style) transparent; outline-offset: var(--outline-offset); } :where(input[type="range"])::-webkit-slider-runnable-track { block-size: var(--range-track-height); inline-size: 100%; background: var(--range-track-background); border: var(--range-track-border); border-radius: var(--range-track-radius); } :where(input[type="range"])::-moz-range-track { block-size: var(--range-track-height); inline-size: 100%; background: var(--range-track-background); border: var(--range-track-border); border-radius: var(--range-track-radius); } :where(input[type="range"])::-webkit-slider-thumb { /* ring renders as box-shadow so it composes with --range-thumb-shadow; the ring widths animate from 0 so the ring grows in smoothly on focus */ --_ring-offset-width: 0px; --_ring-width: 0px; --_ring: color-mix(in oklch, var(--range-ring-color) var(--ring-opacity), transparent); box-shadow: 0 0 0 var(--_ring-offset-width) var(--ring-offset-color), 0 0 0 calc(var(--_ring-offset-width) + var(--_ring-width)) var(--_ring), var(--range-thumb-shadow); -webkit-appearance: none; appearance: none; margin-block-start: var(--range-thumb-offset); inline-size: var(--range-thumb-size); block-size: var(--range-thumb-size); background-color: var(--range-thumb-background); border: var(--range-thumb-border); border-radius: var(--range-thumb-radius); transition: var(--default-transition); } :where(input[type="range"])::-moz-range-thumb { /* ring renders as box-shadow so it composes with --range-thumb-shadow; the ring widths animate from 0 so the ring grows in smoothly on focus */ --_ring-offset-width: 0px; --_ring-width: 0px; --_ring: color-mix(in oklch, var(--range-ring-color) var(--ring-opacity), transparent); appearance: none; inline-size: var(--range-thumb-size); block-size: var(--range-thumb-size); background-color: var(--range-thumb-background); border: var(--range-thumb-border); border-radius: var(--range-thumb-radius); box-shadow: 0 0 0 var(--_ring-offset-width) var(--ring-offset-color), 0 0 0 calc(var(--_ring-offset-width) + var(--_ring-width)) var(--_ring), var(--range-thumb-shadow); transition: var(--default-transition); } :where(input[type="range"]:hover) { --range-thumb-border: 1px solid var(--primary); } :where(input[type="range"]:active) { --range-thumb-shadow: var(--shadow-xs), var(--shadow-ring); cursor: grabbing; } :where(input[type="range"]:focus-visible) { --range-thumb-shadow: var(--shadow-xs), var(--shadow-ring); } :where(input[type="range"]:disabled) { opacity: 0.5; cursor: not-allowed; }}