|$ curl https://forge-ai.dev/api/markdown?path=docs/components/sliders
$cat docs/sliders-&-range-inputs.md
updated Recently·22 min read·published

Sliders & Range Inputs

CSSHTMLTailwindBootstrapUIIntermediate🎯Free Tools
Introduction

Range inputs select values within a continuum — from simple volume sliders to multi-handle price range pickers. This guide covers production-ready slider patterns in plain HTML/CSS, Tailwind CSS, and Bootstrap, including custom styling, step increments, tooltips, and accessibility.

info

Native <input type="range"> provides built-in keyboard support and screen-reader semantics. Pair it with a visible value display and update ARIA live regions for the best experience.
Basic Range Slider

A minimal range input with a live value readout. The native <input type="range"> element provides built-in drag interaction, keyboard support, and screen reader accessibility out of the box.

basic-slider
Live
untitled.html
HTML
1<div class="slider-demo">
2 <div class="slider-group">
3 <label class="slider-label">
4 Volume
5 <span class="slider-value" id="vol-val">
6 50
7 </span>
8 </label>
9 <input type="range" class="slider" id="vol-slider" min="0" max="100" value="50"/>
10 </div>
11</div>
preview
Custom Styled

Custom thumb and track styling with a gradient-filled track that reflects the current value. Inline SVG icons add context without importing a library.

custom-styled
Live
untitled.html
HTML
1<div class="styled-demo">
2 <div class="field">
3 <label>
4 Brightness
5 </label>
6 <div class="track-wrap">
7 <input type="range" class="styled-slider" id="bright" min="0" max="100" value="65"/>
8 <div class="track-fill" id="bright-fill" style="width:65%">
9 </div>
10 </div>
11 <div class="field-info">
12 <span class="fi-icon">
13 &#9728;
14 </span>
15 <span class="fi-val" id="bright-val">
16 65%
17 </span>
18 </div>
19 </div>
20 <div class="field">
21 <label>
22 Contrast
23 </label>
24 <div class="track-wrap">
25 <input type="range" class="styled-slider" id="contrast" min="0" max="100" value="40"/>
26 <div class="track-fill" id="contrast-fill" style="width:40%">
27 </div>
28 </div>
29 <div class="field-info">
30 <span class="fi-icon">
31 &#9680;
32 </span>
33 <span class="fi-val" id="contrast-val">
34 40%
35 </span>
36 </div>
37 </div>
38 <div class="field">
39 <label>
40 Saturation
41 </label>
42 <div class="track-wrap">
43 <input type="range" class="styled-slider" id="sat" min="0" max="100" value="80"/>
44 <div class="track-fill" id="sat-fill" style="width:80%">
45 </div>
46 </div>
47 <div class="field-info">
48 <span class="fi-icon">
49 &#9673;
50 </span>
51 <span class="fi-val" id="sat-val">
52 80%
53 </span>
54 </div>
55 </div>
56</div>
preview
Color Variants

Different accent colors for different contexts — success, info, and danger. Keep the same layout and swap the thumb/track color.

color-variants
Live
untitled.html
HTML
1<div class="variant-demo">
2 <div class="v-field">
3 <label>
4 Success
5 </label>
6 <input type="range" class="slider success" id="v-success" min="0" max="100" value="65"/>
7 <span class="v-val" id="vs-val">
8 65
9 </span>
10 </div>
11 <div class="v-field">
12 <label>
13 Info
14 </label>
15 <input type="range" class="slider info" id="v-info" min="0" max="100" value="40"/>
16 <span class="v-val" id="vi-val">
17 40
18 </span>
19 </div>
20 <div class="v-field">
21 <label>
22 Danger
23 </label>
24 <input type="range" class="slider danger" id="v-danger" min="0" max="100" value="80"/>
25 <span class="v-val" id="vd-val">
26 80
27 </span>
28 </div>
29</div>
preview
Step Slider

A slider with discrete step increments and labeled tick marks. The step attribute constrains values to specific intervals.

step-slider
Live
untitled.html
HTML
1<div class="step-demo">
2 <div class="step-header">
3 <span class="step-title">
4 Zoom Level
5 </span>
6 <span class="step-val" id="step-val">
7 2x
8 </span>
9 </div>
10 <div class="step-track">
11 <input type="range" class="step-slider" id="step-slider" min="0" max="4" step="1" value="2"/>
12 <div class="step-ticks">
13 <span class="tick">
14 </span>
15 <span class="tick">
16 </span>
17 <span class="tick active">
18 </span>
19 <span class="tick">
20 </span>
21 <span class="tick">
22 </span>
23 </div>
24 <div class="step-labels">
25 <span>
26 0.5x
27 </span>
28 <span>
29 1x
30 </span>
31 <span>
32 2x
33 </span>
34 <span>
35 4x
36 </span>
37 <span>
38 8x
39 </span>
40 </div>
41 </div>
42</div>
preview
Price Range (Dual Handle)

A dual-handle range slider for selecting a price range. Two overlapping range inputs create the min/max handles, with the track highlight between them.

price-range
Live
untitled.html
HTML
1<div class="range-demo">
2 <div class="range-header">
3 <span class="range-title">
4 Price Range
5 </span>
6 <span class="range-display">
7 $
8 <span id="min-disp">
9 25
10 </span>
11 — $
12 <span id="max-disp">
13 75
14 </span>
15 </span>
16 </div>
17 <div class="range-track">
18 <div class="range-fill" id="range-fill">
19 </div>
20 <input type="range" class="range-input" id="range-min" min="0" max="100" value="25"/>
21 <input type="range" class="range-input" id="range-max" min="0" max="100" value="75"/>
22 </div>
23 <div class="range-labels">
24 <span>
25 $0
26 </span>
27 <span>
28 $50
29 </span>
30 <span>
31 $100
32 </span>
33 </div>
34</div>
preview
Vertical Slider

Vertical sliders for volume-mixer-style layouts. Each channel displays its value above and label below.

vertical
Live
untitled.html
HTML
1<div class="vert-demo">
2 <div class="vert-group">
3 <input type="range" class="vert-slider" orient="vertical" min="0" max="100" value="30"/>
4 <span class="vert-val" id="v1">
5 30
6 </span>
7 <span class="vert-ch">
8 CH 1
9 </span>
10 </div>
11 <div class="vert-group">
12 <input type="range" class="vert-slider" orient="vertical" min="0" max="100" value="65"/>
13 <span class="vert-val" id="v2">
14 65
15 </span>
16 <span class="vert-ch">
17 CH 2
18 </span>
19 </div>
20 <div class="vert-group">
21 <input type="range" class="vert-slider" orient="vertical" min="0" max="100" value="80"/>
22 <span class="vert-val" id="v3">
23 80
24 </span>
25 <span class="vert-ch">
26 CH 3
27 </span>
28 </div>
29 <div class="vert-group">
30 <input type="range" class="vert-slider" orient="vertical" min="0" max="100" value="45"/>
31 <span class="vert-val" id="v4">
32 45
33 </span>
34 <span class="vert-ch">
35 CH 4
36 </span>
37 </div>
38 <div class="vert-group">
39 <input type="range" class="vert-slider" orient="vertical" min="0" max="100" value="90"/>
40 <span class="vert-val" id="v5">
41 90
42 </span>
43 <span class="vert-ch">
44 CH 5
45 </span>
46 </div>
47</div>
preview
Labeled Sections

A slider with named zones that highlight as the handle passes through them — useful for settings that have named tiers or thresholds.

labeled-zones
Live
untitled.html
HTML
1<div class="zone-demo">
2 <div class="zone-header">
3 <span class="zone-title">
4 Quality Preset
5 </span>
6 <span class="zone-name" id="zone-name">
7 Balanced
8 </span>
9 </div>
10 <div class="zone-track">
11 <div class="zone-fill" id="zone-fill">
12 </div>
13 <input type="range" class="zone-slider" id="zone-slider" min="0" max="4" step="1" value="2"/>
14 <div class="zone-segments">
15 <span class="seg" data-zone="Ultra Fast">
16 </span>
17 <span class="seg" data-zone="Fast">
18 </span>
19 <span class="seg active" data-zone="Balanced">
20 </span>
21 <span class="seg" data-zone="Quality">
22 </span>
23 <span class="seg" data-zone="Ultra">
24 </span>
25 </div>
26 </div>
27 <div class="zone-labels">
28 <span>
29 Ultra Fast
30 </span>
31 <span>
32 Fast
33 </span>
34 <span>
35 Balanced
36 </span>
37 <span>
38 Quality
39 </span>
40 <span>
41 Ultra
42 </span>
43 </div>
44</div>
preview
Disabled & Readonly

Sliders in disabled and read-only states. Disabled prevents all interaction and dims the control; readonly preserves the value but blocks user changes.

disabled-states
Live
untitled.html
HTML
1<div class="disabled-demo">
2 <div class="d-field">
3 <label>
4 Active Slider
5 </label>
6 <input type="range" class="d-slider" id="d-active" min="0" max="100" value="60"/>
7 <span class="d-val" id="d-active-val">
8 60
9 </span>
10 </div>
11 <div class="d-field">
12 <label>
13 Disabled Slider
14 </label>
15 <input type="range" class="d-slider disabled" min="0" max="100" value="40" disabled/>
16 <span class="d-val dim">
17 40
18 </span>
19 </div>
20 <div class="d-field">
21 <label>
22 Readonly Slider
23 </label>
24 <input type="range" class="d-slider readonly" min="0" max="100" value="75" readonly/>
25 <span class="d-val">
26 75
27 </span>
28 </div>
29</div>
preview
Slider with Tooltip

A slider with a floating tooltip that follows the thumb and displays the current value.

slider-tooltip
Live
untitled.html
HTML
1<div class="tip-demo">
2 <div class="tip-group">
3 <div class="tip-wrap">
4 <div class="tip-bubble" id="tip-bubble">
5 50
6 </div>
7 <input type="range" class="tip-slider" id="tip-slider" min="0" max="100" value="50"/>
8 </div>
9 <div class="tip-labels">
10 <span>
11 0
12 </span>
13 <span>
14 100
15 </span>
16 </div>
17 </div>
18</div>
preview
CSS Pseudo-Elements Reference

The range input exposes several pseudo-elements for styling. WebKit and Mozilla use different naming conventions, so target both for cross-browser compatibility.

slider-pseudo-elements.css
CSS
1/* WebKit (Chrome, Safari, Edge) */
2input[type="range"]::-webkit-slider-runnable-track {
3 height: 6px;
4 background: #2A2A3E;
5 border-radius: 3px;
6}
7
8input[type="range"]::-webkit-slider-thumb {
9 appearance: none;
10 width: 18px;
11 height: 18px;
12 border-radius: 50%;
13 background: #00FF41;
14 margin-top: -6px; /* center on track */
15}
16
17/* Mozilla (Firefox) */
18input[type="range"]::-moz-range-track {
19 height: 6px;
20 background: #2A2A3E;
21 border-radius: 3px;
22}
23
24input[type="range"]::-moz-range-thumb {
25 width: 18px;
26 height: 18px;
27 border-radius: 50%;
28 background: #00FF41;
29 border: none;
30}
HTML Structure

The range input follows a semantic pattern: a <label> connected via for, the <input type="range"> with min/max/step/value attributes, and an aria live region for the current value.

slider-structure.html
HTML
1<label for="volume">Volume</label>
2
3<input type="range"
4 id="volume"
5 min="0" max="100"
6 value="50" step="1"
7 aria-valuenow="50"
8 aria-valuemin="0"
9 aria-valuemax="100" />
10
11<span aria-live="polite">50</span>
Accessibility

Sliders must be operable with a keyboard, announce their value to screen readers, and remain visible across states.

  • Use a real <input type="range"> instead of a custom div so keyboard and ARIA support come for free.
  • Connect every slider to a visible <label> with htmlFor or wrap the input in a label.
  • Provide a live value display with aria-live="polite" so changes are announced without interrupting the user.
  • Ensure the thumb is at least 44×44 px on touch devices; increase padding or thumb size if needed.
  • Keep focus indicators visible — avoid removing outlines without replacing them with a high-contrast ring or box-shadow.
  • For disabled sliders, use the disabled attribute and keep the label readable; do not rely on color alone.
Best Practices

info

Always pair a range input with a visible value display. Users need precise feedback — the slider thumb alone is not enough to communicate the exact value. A tooltip or numeric readout works best.

warning

Custom-styled sliders require separate pseudo-element rules for -webkit- and -moz- prefixes. Test on both Chrome and Firefox to ensure consistent appearance across browsers.

best practice

Use the step attribute for discrete values (e.g., quality presets, zoom levels). For continuous values like volume or brightness, omit step or set it to 1 for smooth movement.
  • Always include aria-valuemin, aria-valuemax, and aria-valuenow for screen readers. The browser updates aria-valuenow automatically, but custom displays need manual updates.
  • Use aria-live="polite" on the value display so assistive technologies announce changes without interrupting the current task.
  • Minimum touch target for slider thumbs should be 44×44px on mobile — increase thumb size or add invisible padding to meet WCAG touch target requirements.
  • For dual-handle range sliders, ensure handles cannot cross each other to maintain logical min/max ordering. Clamp values on the input event.
  • Consider providing a number input alongside the slider for users who need precise values. Sync both inputs bidirectionally.
  • Use font-variant-numeric: tabular-nums on value displays to prevent layout shifts as digits change width.

Community

Get help on Slack, Discord or VIP

Stuck on a guide? Join the community and ask.