Sliders let people pick from a range of values. An
<input type="range"> is the control. A wrapping
.slider — or .range, or a
<label> — is the host. The plugin is
Expressive.Slider, and Expressive.Range
still resolves to it.
Three variants: standard (active from the start), centered (active grows from the midpoint), and range (two handles, active between them). Horizontal or vertical. Five sizes: XS (the default), S, M, L, XL. Optional inset icon, discrete stops, and a value indicator.
Tokens follow the
M3 slider spec
(Expressive). The handle is a 4dp stop with a 6dp gap to each
track. Active is primary; inactive is
secondary-container. The end of an inactive track
has a 4dp stop. The value label is a 40dp
inverse-surface bubble.
Range is not in AutoInit(). Importing the IIFE
bundle calls Expressive.Range.Init(), which
starts every input[type=range] already in the
document and keeps the active track in sync.
<label>
Volume
<input type="range" min="0" max="100" value="40">
</label>
Variants
Standard is the default. centered grows the active
track from 50%. A range slider is two inputs in one
.range host.
<div class="slider">
<input type="range" min="0" max="100" value="40" aria-label="Standard">
</div>
<div class="slider centered">
<input type="range" min="0" max="100" value="30" aria-label="Centered">
</div>
<div class="slider">
<input type="range" min="0" max="100" value="25" aria-label="Range start">
<input type="range" min="0" max="100" value="75" aria-label="Range end">
</div>
Sizes
Default is XS (16dp track, 44dp handle).
s / small is S,
m / medium is M,
l / large is L,
xl is XL. Scope them on the host.
<div class="slider s">…</div>
<div class="slider m">…</div>
<div class="slider l">…</div>
<div class="slider xl">…</div>
Inset icon, stops, value
A leading icon sits in the active track —
M, L, and XL are tall enough. stops plus
step paints ticks on the active track. Dragging
shows the value in a 40dp bubble.
<div class="slider m">
<span class="material-symbols" aria-hidden="true">volume_up</span>
<input type="range" min="0" max="100" value="55" aria-label="Volume">
</div>
<div class="slider stops">
<input type="range" min="0" max="100" step="20" value="40" aria-label="Stops">
</div>
Vertical
vertical stands the track up. Minimum is at the
bottom.
<div class="slider vertical m">
<input type="range" min="0" max="100" value="60" aria-label="Level">
</div>
Disabled
The native disabled attribute drops the control to 38%.
Initialization
Put the script after the inputs, or call init
yourself. There are no options. For a slider added after load:
document.addEventListener('DOMContentLoaded', function() {
const elems = document.querySelectorAll('input[type=range]');
Expressive.Range.init(elems);
});
Expressive.Range.init(document.querySelector('#volume'));
Methods
const instance = Expressive.Range.getInstance(elem);
instance.destroy();
Destroy the plugin instance, remove the value label, and tear down its event handlers.