|$ 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

◆CSS◆HTML◆Tailwind◆Bootstrap◆UI◆Intermediate🎯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.