webdevpuneet.com

Range Slider — Free HTML CSS JS Custom Slider Snippet

Range Slider · Forms · Plain HTML, CSS & JS · Live preview

CategoryForms

Copy & paste

Source Code

<div class="demo">
  <div class="field">
    <div class="row"><label>Budget</label><span id="budget-val">$2,500</span></div>
    <input type="range" id="budget" min="0" max="10000" value="2500" step="100" oninput="updateBudget(this.value)" />
    <div class="ticks"><span>$0</span><span>$5k</span><span>$10k</span></div>
  </div>
  <div class="field">
    <div class="row"><label>Team size</label><span id="team-val">5 people</span></div>
    <input type="range" id="team" min="1" max="50" value="5" oninput="updateTeam(this.value)" />
  </div>
  <div class="field">
    <div class="row"><label>Opacity</label><span id="opacity-val">75%</span></div>
    <input type="range" id="opacity" min="0" max="100" value="75" class="purple" oninput="updateOpacity(this.value)" />
    <div class="preview-box" id="preview-box"></div>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

accent-color property recolours track and thumb natively — one CSS line
::-webkit-slider-thumb override for precise thumb control in Chrome/Safari
White border + matching box-shadow ring creates a polished thumb appearance
Live value display: oninput triggers dedicated format functions per slider
toLocaleString() for comma-formatted budget values
Singular/plural handling: person vs people based on value
Opacity slider drives a live CSS style change on a preview element
Tick mark labels below slider track
Export as HTML file, React JSX, or React + Tailwind CSS
Live split-pane editor — preview updates as you type

About this UI Snippet

Range Slider — Custom CSS Track & Thumb, accent-color, Live Value Display

Screenshot of the Range Slider snippet rendered live

The range slider is one of the most useful but hardest-to-style native form elements — for a two-handle version see the multi-range slider, and for a circular control the rotary knob. The default <input type="range"> looks different on every browser and operating system. This snippet shows three techniques for styling it consistently and wiring live value display.

The accent-color approach

input[type="range"] { accent-color: #6366f1 } is the modern approach — it recolours the thumb and filled track portion using the browser's native accent-color support. This is the simplest cross-browser technique and works in all modern browsers without any pseudo-element overrides — the usage calculator builds on it for live pricing. For the purple variant, input[type="range"].purple { accent-color: #8b5cf6 } swaps the colour with a single property.

Custom WebKit thumb

For precise thumb styling in Chrome and Safari, ::-webkit-slider-thumb overrides the native thumb: width: 18px; height: 18px; border-radius: 50%; background: #6366f1; border: 3px solid #fff; box-shadow: 0 0 0 2px #6366f1. The white border and matching box-shadow create a ringed thumb that looks clean on any background.

Live value display

Each slider calls a dedicated update function via oninput. updateBudget(v) sets the text of a <span id="budget-val"> with formatted output: `'

The accent-color property

Modern browsers support accent-color: #6366f1 on range inputs to colour the track fill and thumb with one CSS property. For browsers that do not support it, the WebKit and Mozilla pseudo-element overrides provide consistent cross-browser styling. Both approaches are included in the snippet.

Customising the live value format

Each slider calls a dedicated update function on oninput. Change the format string in each function to match your use case: currency with toLocaleString(), distance as Nkm, time as Nh Nm, weight as Nkg. The format function runs on every input event at the native frame rate — no debounce is needed for simple text updates because range inputs only fire while the user is dragging.

Dual-handle range slider for price range selection

For a min/max selector with two handles, use two overlapping range inputs. Enforce constraints in JavaScript: the lower handle cannot exceed the upper, and vice versa. A CSS gradient between the two current values fills only the selected range area, giving users clear visual feedback about the selected window. Use input.value and the min/max attributes to enforce that neither handle crosses the other.

The accent-color property

Modern browsers support accent-color: #6366f1 on range inputs to colour the track fill and thumb with one CSS property. For browsers that do not support it, the WebKit and Mozilla pseudo-element overrides provide consistent cross-browser styling. Both approaches are included in the snippet.

Customising the live value format

Each slider calls a dedicated update function on oninput. Change the format string in each function to match your use case: currency with toLocaleString(), distance as Nkm, time as Nh Nm, weight as Nkg. The format function runs on every input event at the native frame rate — no debounce is needed for simple text updates because range inputs only fire while the user is dragging.

Dual-handle range slider for price range selection

For a min/max selector with two handles, use two overlapping range inputs. Enforce constraints in JavaScript: the lower handle cannot exceed the upper, and vice versa. A CSS gradient between the two current values fills only the selected range area, giving users clear visual feedback about the selected window.

The accent-color property

Modern browsers support accent-color: #6366f1 on range inputs to colour the track fill and thumb with one CSS property. For browsers that do not support it, the WebKit and Mozilla pseudo-element overrides provide consistent cross-browser styling. Both approaches are included in the snippet.

Customising the live value format

Each slider calls a dedicated update function on oninput. Change the format string in each function to match your use case: currency with toLocaleString(), distance as Nkm, time as Nh Nm, weight as Nkg. The format function runs on every input event at the native frame rate — no debounce is needed for simple text updates because range inputs only fire while the user is dragging.

Dual-handle range slider for price range selection

For a min/max selector with two handles, use two overlapping range inputs. Enforce constraints in JavaScript: the lower handle cannot exceed the upper, and vice versa. A CSS gradient between the two current values fills only the selected range area, giving users clear visual feedback about the selected window.

Step by step

How to Use

  1. 1
    Drag all three slidersDrag the Budget, Team size, and Opacity sliders in the preview. Each shows a different live value format and the third changes the preview box opacity.
  2. 2
    Change the min, max, and stepIn the HTML panel, update the min, max, and step attributes on each input[type="range"] to match your data range.
  3. 3
    Update the value formatIn the JS panel, update the update functions to format the value for your use case — currency, percentage, unit label.
  4. 4
    Change the accent colourUpdate accent-color: #6366f1 in the CSS panel to your brand colour. Also update the matching thumb background and box-shadow.
  5. 5
    Set the initial valueUpdate the value attribute on the input and call the corresponding update function once on page load to show the initial formatted value.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component, or "Tailwind" for a React + Tailwind version.

Real-world uses

Common Use Cases

Budget and pricing configurators
Use the budget slider in SaaS pricing pages where the slider drives a live price update. The toLocaleString formatting handles large numbers cleanly.
Settings and preference controls
Volume, brightness, font size, playback speed — any setting where a number input is too precise and a dropdown has too few options.
Colour and opacity controls
The opacity slider wires directly to a CSS style change. Extend the pattern for hue, saturation, or blur intensity controls in a design tool.
Learn accent-color and WebKit thumb styling
Edit the accent-color and ::-webkit-slider-thumb values to see how each affects the slider appearance in Chrome vs Firefox.
Team size and capacity planners
Use the team slider for onboarding forms where users select team size. The singular/plural handling keeps the label grammatically correct.
Controlled slider in React
Use the JSX export. Bind value={sliderValue} and onChange={e => setSliderValue(+e.target.value)} for a fully controlled React input.

Got questions?

Frequently Asked Questions

accent-color: #6366f1 is a CSS property that recolours interactive elements — checkboxes, radios, progress bars, and range inputs — using the browser native rendering. It colours both the thumb and the filled track portion without requiring pseudo-element overrides. It is the simplest cross-browser approach for basic colour theming.

::-webkit-slider-thumb sets background: #6366f1 and border: 3px solid #fff (white border). box-shadow: 0 0 0 2px #6366f1 adds a matching outer ring. The white border separates the thumb from the ring, creating a bullseye appearance. This works in Chrome and Safari; Firefox uses -moz-range-thumb.

Each slider has an oninput="updateX(this.value)" attribute. The update function receives the string value, formats it (currency, plural, percentage), and sets the textContent of the matching display span. The +v coercion converts the string to a number for calculations.

Add a <datalist id="ticks"> with <option value="0">, <option value="50">, <option value="100"> etc. Add list="ticks" to the input. The browser renders native tick marks at each option value. The .ticks div in this snippet is a manual CSS alternative for more styling control.

Call the update function once on page load with the slider's initial value: updateBudget(document.querySelector("input").value). Or set the display span text directly in the HTML to match the input value attribute.

Yes. Click "JSX" for a React component. Use a controlled input: <input type="range" value={value} onChange={e => setValue(+e.target.value)} />. Display the formatted value next to the slider. The CSS accent-color and ::-webkit-slider-thumb styles work unchanged in React.