Skip to content

Range

The range source mirrors a slider into --live-value and --live-value-pct. Bind it to the <input>, or to a container that holds one so siblings can read the value too. Drag the slider: the readout, the fill bar, and a @container style() milestone all react in CSS.

--live-value --live-value-pct

Drag the slider. At exactly 100, a @container style() query flips the badge to max, a branch var() can't make.

One attribute on the wrapper binds it; the inner <input> is found automatically:

<script type="module">import 'prop-for-that/auto'</script>
<div data-props-for="range">
<input type="range" min="0" max="100">
</div>

Everything visible is CSS reading the value:

/* fill bar */
.bar i { scale: var(--live-value-pct) 1; }
/* numeric readout, no JS reads the value */
.value::after { counter-reset: v calc(var(--live-value)); content: counter(v); }
/* discrete milestone, only a style query can express it */
@container style(--live-value: 100) {
.badge { color: var(--accent); }
}