Slider
hc-slider is applied to a native <input type="range">. Keyboard
navigation (←/→, Home, End, PageUp, PageDown), form participation,
and screen-reader announcement of role + value + range all come for
free from the browser; only the visual chrome is replaced via
appearance: none plus per-vendor pseudo-elements.
Basic example
Section titled “Basic example”Volume
<label> Volume <input class="hc-slider" type="range" min="0" max="100" value="40"></label>import { installSlider } from '@hypermedia-components/core';installSlider();How the fill color works
Section titled “How the fill color works”Firefox renders the 0→value portion of the track natively via
::-moz-range-progress. WebKit and Chromium have no equivalent
pseudo, so the same effect is painted with a linear-gradient
that reads a --hc-slider-value custom property (a 0-100
percentage).
installSlider() keeps --hc-slider-value synchronised with each
slider’s current value via the input event — call it once and
forget. For server-rendered pages, write the property directly:
<input class="hc-slider" type="range" min="0" max="100" value="40" style="--hc-slider-value: 40">That way the fill renders correctly on first paint even before JavaScript loads.
Variants
Section titled “Variants”data-variant accepts success, warning, and error for
non-default fill colors. The thumb border tracks the variant too.
<input class="hc-slider" type="range" min="0" max="100" value="60" aria-label="Default"><input class="hc-slider" type="range" min="0" max="100" value="60" data-variant="success" aria-label="Success"><input class="hc-slider" type="range" min="0" max="100" value="60" data-variant="warning" aria-label="Warning"><input class="hc-slider" type="range" min="0" max="100" value="60" data-variant="error" aria-label="Error">data-size accepts sm, md (default), and lg. Track height
and thumb size scale together.
<input class="hc-slider" type="range" min="0" max="100" value="40" data-size="sm" aria-label="Small"><input class="hc-slider" type="range" min="0" max="100" value="40" aria-label="Default"><input class="hc-slider" type="range" min="0" max="100" value="40" data-size="lg" aria-label="Large">Disabled
Section titled “Disabled”Use the native disabled attribute. The track and thumb dim and the
control stops responding to pointer and keyboard input.
<input class="hc-slider" type="range" min="0" max="100" value="40" disabled aria-label="Disabled">Vertical orientation
Section titled “Vertical orientation”Add data-orientation="vertical" to stand the slider up. This uses the
modern, native approach — CSS writing-mode
— so the control stays a real <input type="range">: the OS thumb, the full
keyboard (↑ / ↓ step, Home / End,
PageUp / PageDown), form participation, and
screen-reader value announcement all keep working. The maximum sits at the
top, so ↑ increases the value.
<input class="hc-slider" type="range" min="0" max="100" value="40" data-orientation="vertical" aria-label="Volume">Set the height with the --hc-slider-length custom property (default
12rem):
<input class="hc-slider" type="range" … data-orientation="vertical" style="--hc-slider-length: 16rem">htmx usage
Section titled “htmx usage”The slider participates in form submissions like any other input.
For instant updates, listen to input:
<input class="hc-slider" type="range" min="0" max="100" value="40" name="volume" data-hx-post="/preferences/volume" data-hx-trigger="input changed delay:200ms" data-hx-include="this">Accessibility
Section titled “Accessibility”- Always give the slider an accessible name — wrap it in a
<label>or setaria-label. - The native input handles
←/→(step),Home/End(min / max),PageUp/PageDown(large step) without any custom JS. - For ranges where the displayed value differs from the underlying
number (e.g. percent of a non-100 max), set
aria-valuetext="40 %"so screen readers announce the formatted string. - Don’t remove the focus outline. The thumb receives a
box-shadowring through--hc-color-focus-ring.
Range constraints (single thumb)
Section titled “Range constraints (single thumb)”A native <input type="range"> is a single-thumb control. Multi-
thumb range pickers (price range, brightness span, etc.) are out of
scope for this component — that pattern requires a custom DOM
shell and a much larger behavior to manage the two thumbs
manually. Until that lands, two single sliders side-by-side (with
linked min/max constraints in form-validation JS) is the recommended
pattern.
Theming tokens
Section titled “Theming tokens”Component tokens (in component.tokens.json):
| Token path | Purpose |
|---|---|
slider.track-height / track-bg | Track. |
slider.thumb-size / thumb-bg / thumb-border | Thumb. |
slider.fill | Default fill color (action.primary). |
slider.success-fill / warning-fill / error-fill | Variant fills. |
slider.success-thumb-border / warning-thumb-border / error-thumb-border | Variant thumb borders. |
slider.disabled-fill | Disabled thumb border color. |
slider.radius | Track + thumb corner radius. |
slider.sm.* / lg.* | Sized variants. |
CSS variables
Section titled “CSS variables”Show the generated CSS variables
--hc-slider-track-height | -track-bg | -radius--hc-slider-thumb-size | -thumb-bg | -thumb-border--hc-slider-fill | -success-fill | -warning-fill | -error-fill--hc-slider-success-thumb-border | -warning-thumb-border | -error-thumb-border--hc-slider-disabled-fill--hc-slider-sm-track-height | -sm-thumb-size--hc-slider-lg-track-height | -lg-thumb-size--hc-slider-value (0-100, kept in sync by installSlider)--hc-slider-length (vertical track length; default 12rem)--hc-color-focus-ring (inherited from data-color)