Range input
Preview Available in release assets
Theme a native range input while retaining its keyboard, pointer, touch, validation, and submission behavior.
Range input primary example
<div class="thin-field">
<label for="volume">Volume</label>
<input class="thin-range" id="volume" name="volume" type="range" min="0" max="100" value="60">
<output for="volume">60%</output>
</div>Show code
<div class="thin-field">
<label for="volume">Volume</label>
<input class="thin-range" id="volume" name="volume" type="range" min="0" max="100" value="60">
<output for="volume">60%</output>
</div>Variant gallery
Each authored example uses the production assets and includes copyable markup.
Native horizontal level
Arrow keys adjust the native value; Home and End reach its bounds. Ordinary GET submission sends the chosen number. No stale output label or scripted slider is added.
<form action="/mix" method="get" style="display: grid; gap: 1rem">
<div class="thin-field" style="overflow-wrap: anywhere">
<label for="range-horizontal">Level</label>
<input class="thin-range" id="range-horizontal" name="level" type="range" min="0" max="100" step="5" value="50" aria-describedby="range-horizontal-hint" >
<small class="thin-hint" id="range-horizontal-hint">0 to 100, in steps of 5. The native control exposes its current value.</small>
</div>
<button class="thin-button">Apply level</button>
</form>Show code
<form action="/mix" method="get" style="display: grid; gap: 1rem">
<div class="thin-field" style="overflow-wrap: anywhere">
<label for="range-horizontal">Level</label>
<input class="thin-range" id="range-horizontal" name="level" type="range" min="0" max="100" step="5" value="50" aria-describedby="range-horizontal-hint" >
<small class="thin-hint" id="range-horizontal-hint">0 to 100, in steps of 5. The native control exposes its current value.</small>
</div>
<button class="thin-button">Apply level</button>
</form>Native vertical level
An authored vertical writing mode and RTL direction draw the range from bottom to top in supporting browsers. Native keyboard operation remains intact. Home and End reach opposite bounds; their order in a bottom-to-top range differs between browser engines.
<div class="thin-field" style="overflow-wrap: anywhere">
<label for="range-vertical">Vertical level</label>
<input class="thin-range" id="range-vertical" name="level" type="range" min="0" max="100" step="5" value="50" aria-describedby="range-vertical-hint" style="writing-mode: vertical-lr; direction: rtl; inline-size: 12rem; block-size: 3rem">
<small class="thin-hint" id="range-vertical-hint">0 to 100, in steps of 5. The native control exposes its current value.</small>
</div>Show code
<div class="thin-field" style="overflow-wrap: anywhere">
<label for="range-vertical">Vertical level</label>
<input class="thin-range" id="range-vertical" name="level" type="range" min="0" max="100" step="5" value="50" aria-describedby="range-vertical-hint" style="writing-mode: vertical-lr; direction: rtl; inline-size: 12rem; block-size: 3rem">
<small class="thin-hint" id="range-vertical-hint">0 to 100, in steps of 5. The native control exposes its current value.</small>
</div>Anatomy
- Associated label
- input[type=range]
- Optional authored output
Variants and sizes
- Browser-native track and thumb — shown above
- Vertical orientation where supported by authored HTML — shown above
States and difficult content
Rendered fixtures exercise authored content and constrained layouts with the same production assets.
Minimum, intermediate and maximum
These three independent native ranges start at the lower bound, midpoint and upper bound. Tab into each to inspect focus, then adjust it with the keyboard.
<section style="display: grid; gap: 1rem">
<div class="thin-field" style="overflow-wrap: anywhere">
<label for="range-min">Minimum level</label>
<input class="thin-range" id="range-min" name="level" type="range" min="0" max="100" step="5" value="0" aria-describedby="range-min-hint" >
<small class="thin-hint" id="range-min-hint">0 to 100, in steps of 5. The native control exposes its current value.</small>
</div>
<div class="thin-field" style="overflow-wrap: anywhere">
<label for="range-mid">Intermediate level</label>
<input class="thin-range" id="range-mid" name="level" type="range" min="0" max="100" step="5" value="50" aria-describedby="range-mid-hint" >
<small class="thin-hint" id="range-mid-hint">0 to 100, in steps of 5. The native control exposes its current value.</small>
</div>
<div class="thin-field" style="overflow-wrap: anywhere">
<label for="range-max">Maximum level</label>
<input class="thin-range" id="range-max" name="level" type="range" min="0" max="100" step="5" value="100" aria-describedby="range-max-hint" >
<small class="thin-hint" id="range-max-hint">0 to 100, in steps of 5. The native control exposes its current value.</small>
</div>
</section>Show code
<section style="display: grid; gap: 1rem">
<div class="thin-field" style="overflow-wrap: anywhere">
<label for="range-min">Minimum level</label>
<input class="thin-range" id="range-min" name="level" type="range" min="0" max="100" step="5" value="0" aria-describedby="range-min-hint" >
<small class="thin-hint" id="range-min-hint">0 to 100, in steps of 5. The native control exposes its current value.</small>
</div>
<div class="thin-field" style="overflow-wrap: anywhere">
<label for="range-mid">Intermediate level</label>
<input class="thin-range" id="range-mid" name="level" type="range" min="0" max="100" step="5" value="50" aria-describedby="range-mid-hint" >
<small class="thin-hint" id="range-mid-hint">0 to 100, in steps of 5. The native control exposes its current value.</small>
</div>
<div class="thin-field" style="overflow-wrap: anywhere">
<label for="range-max">Maximum level</label>
<input class="thin-range" id="range-max" name="level" type="range" min="0" max="100" step="5" value="100" aria-describedby="range-max-hint" >
<small class="thin-hint" id="range-max-hint">0 to 100, in steps of 5. The native control exposes its current value.</small>
</div>
</section>Disabled native range
The disabled attribute prevents interaction and excludes the control from ordinary form data.
<div class="thin-field" style="overflow-wrap: anywhere">
<label for="range-disabled">Unavailable level</label>
<input class="thin-range" id="range-disabled" name="level" type="range" min="0" max="100" step="5" value="50" aria-describedby="range-disabled-hint" disabled>
<small class="thin-hint" id="range-disabled-hint">0 to 100, in steps of 5. The native control exposes its current value.</small>
</div>Show code
<div class="thin-field" style="overflow-wrap: anywhere">
<label for="range-disabled">Unavailable level</label>
<input class="thin-range" id="range-disabled" name="level" type="range" min="0" max="100" step="5" value="50" aria-describedby="range-disabled-hint" disabled>
<small class="thin-hint" id="range-disabled-hint">0 to 100, in steps of 5. The native control exposes its current value.</small>
</div>- Minimum — shown above
- Intermediate — shown above
- Maximum — shown above
- Disabled — shown above
- Focused — shown above
Interaction and keyboard behavior
Arrow, Page Up/Down, Home/End, pointer, and touch behavior remain browser-owned. Updating an output is application behavior.
Accessibility
Always provide an accessible name. Expose the current value in nearby text only when users need a formatted value.
- Contract
NATIVE- Basis
- Native <input type="range"> and <input type="file">; no APG widget
- Evidence
tests/unit/library/form-inputs.test.ts
API
Use input[type=range].thin-range and native min, max, step, value, name, and disabled attributes.
Behavior tier: native
Structured host, property, and example tables are not authored for this item yet. Use the summary above and the primary example.
Fallback
The native range remains keyboard operable and submits its value without CSS or JavaScript.
Assets and dependencies
/components.css
Dependencies: None
Source: packages/ui/src/items/range-input/style.ts
Composition
Derived from the examples and style specs, not authored.