Range Slider
Single and dual-handle range inputs with value display, step markers, and live feedback.
Single Handle
Basic range input using DaisyUI's range class. Value updates live via Alpine. Use when the user selects a single point on a scale — volume, zoom level, quantity.
Small
Medium (default)
Large
Disabled
Secondary colour
With min / max labels
<div x-data="{ val: 55 }" class="flex items-center gap-3">
<input type="range" min="0" max="100"
x-model="val"
class="range range-sm range-primary flex-1"/>
<span class="text-sm font-medium tabular-nums w-8 text-right"
x-text="val"></span>
</div>
Value Tooltip on Drag
The bubble appears on focus / mousedown and hides on blur / mouseup, tracking the thumb position via an inline left calculated from the current value. Useful for scrubbers where the precise number matters.
<div class="rs-tooltip-wrap"
x-data="{ val: 42, show: false }"
@mousedown="show = true" @touchstart="show = true"
@mouseup.window="show = false" @touchend.window="show = false">
<span class="rs-tooltip"
x-show="show"
:style="`left: calc(${(val/100)*100}% + ${8-(val/100)*16}px)`"
x-text="val + '%'"></span>
<input type="range" min="0" max="100"
x-model="val"
class="range range-sm range-primary w-full"/>
</div>
Step Markers
Tick marks and labels rendered below the track reinforce the available steps. The step attribute on the input snaps the thumb to the defined intervals.
<div x-data="{ val: 2 }">
<input type="range" min="0" max="4" step="1"
x-model="val"
class="range range-sm range-primary w-full"/>
<!-- Tick marks -->
<div class="rs-ticks">
<div class="rs-tick">
<div class="rs-tick-mark"></div>
<span class="rs-tick-label">XS</span>
</div>
<!-- …repeat for each step -->
</div>
</div>
Dual Handle — Price Range
Two <input type="range"> elements layered on the same track. Alpine enforces min ≤ max on every input event. The filled segment between the handles is a positioned .rs-dual-fill div driven by inline styles. Common in filter sidebars and product search.
<div x-data="{
lo: 80, hi: 420, min: 0, max: 500,
setLo(v) { this.lo = Math.min(Number(v), this.hi - 10); },
setHi(v) { this.hi = Math.max(Number(v), this.lo + 10); },
pct(v) { return ((v - this.min)/(this.max - this.min)*100).toFixed(2); }
}">
<div class="rs-dual-track">
<div class="rs-dual-bar">
<div class="rs-dual-fill"
:style="`left:${pct(lo)}%;width:${pct(hi)-pct(lo)}%`">
</div>
</div>
<input type="range" :min="min" :max="max" step="10"
:value="lo" @input="setLo($event.target.value)"
aria-label="Minimum"/>
<input type="range" :min="min" :max="max" step="10"
:value="hi" @input="setHi($event.target.value)"
aria-label="Maximum"/>
</div>
<div class="flex justify-between text-xs text-base-content/50">
<span>$0</span><span>$500</span>
</div>
</div>
Custom Track Colours
DaisyUI exposes range-primary, range-secondary, range-accent, range-success, range-warning, and range-error. Use semantic colours to communicate meaning — green for "good", red for "danger".
<!-- DaisyUI semantic colour modifiers -->
<input class="range range-xs range-primary" .../>
<input class="range range-xs range-secondary" .../>
<input class="range range-xs range-accent" .../>
<input class="range range-xs range-success" .../>
<input class="range range-xs range-warning" .../>
<input class="range range-xs range-error" .../>
Inside a Form
Paired with a fieldset label and helper text. The live badge keeps the value visible without a separate input, which reduces form clutter.
<fieldset x-data="{ val: 70 }">
<div class="flex items-center justify-between mb-1">
<legend class="fieldset-legend">Volume</legend>
<span class="badge badge-ghost badge-sm" x-text="val + '%'"></span>
</div>
<input type="range" min="0" max="100"
x-model="val"
class="range range-sm range-primary w-full"
aria-label="Volume"/>
<p class="fieldset-label mt-1">Applies to all notification sounds.</p>
</fieldset>