SolutionsCase StudiesAI ToolsResourcesAboutContact
Get Your Free AI Automation Audit Book a Free 30-Minute Strategy Call
Playground~/frontend Open editor

~/css/tailwind-range-sliders

6 Tailwind Range Sliders

1 Tailwind5 with JSPublished 2026-10-05Free · no sign-up

Six sliders that keep the native range input underneath: a quick accent-colour slider, a fully custom thumb, a filled track, a stepped control with labels, a minimum and maximum price range and a thermostat with step buttons.

01. Tailwind accent-color Slider

TailwindRange

The quickest styled slider: the accent- utility recolours the browser's own range input, keeping its native look, keyboard support and touch target. An output element shows the current value next to the label.

View code
<div class="w-full max-w-xs">
  <div class="flex items-center justify-between text-sm font-semibold text-slate-800"><label for="twrs1">Brightness</label><output id="twrs1o" for="twrs1">60%</output></div>
  <input id="twrs1" type="range" min="0" max="100" value="60" class="mt-2 w-full accent-indigo-600">
</div>
var r = document.getElementById('twrs1'), o = document.getElementById('twrs1o');
r.oninput = function () { o.textContent = r.value + '%'; };

02. Tailwind Custom Thumb Slider

TailwindRangePseudo-elements

A fully custom slider styled with arbitrary variants that target the thumb pseudo-elements: [&::-webkit-slider-thumb] for Chrome and Safari and [&::-moz-range-thumb] for Firefox. The thumb gets a glowing halo and the outline shows on keyboard focus.

View code
<div class="w-full max-w-xs">
  <label for="twrs2" class="text-sm font-semibold text-slate-200">Volume</label>
  <input id="twrs2" type="range" value="40" class="mt-3 h-2 w-full cursor-pointer appearance-none rounded-full bg-slate-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-cyan-300 [&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-0 [&::-moz-range-thumb]:bg-cyan-400 [&::-webkit-slider-thumb]:size-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-cyan-400 [&::-webkit-slider-thumb]:[box-shadow:0_0_0_5px_rgba(34,211,238,.25)]">
</div>

03. Tailwind Slider with Filled Track

TailwindRangeJS

The part of the track before the thumb fills with colour. A custom property holds the percentage and an arbitrary background utility draws a hard-stop gradient from it, so the fill works the same in every browser.

View code
<div class="w-full max-w-xs">
  <div class="flex justify-between text-sm font-semibold text-slate-800"><label for="twrs3">Monthly budget</label><output id="twrs3o" for="twrs3">$1,200</output></div>
  <input id="twrs3" type="range" min="200" max="5000" step="100" value="1200" style="--p:20.8%" class="mt-3 h-2 w-full cursor-pointer appearance-none rounded-full [background:linear-gradient(to_right,#047857_var(--p),#cbd5e1_var(--p))] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-emerald-700 [&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-white [&::-moz-range-thumb]:bg-emerald-700 [&::-webkit-slider-thumb]:size-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-white [&::-webkit-slider-thumb]:bg-emerald-700 [&::-webkit-slider-thumb]:shadow">
</div>
var r = document.getElementById('twrs3'), o = document.getElementById('twrs3o');
function u() { r.style.setProperty('--p', (r.value - r.min) / (r.max - r.min) * 100 + '%'); o.textContent = '$' + Number(r.value).toLocaleString('en-US'); }
r.oninput = u; u();

04. Tailwind Stepped Slider with Labels

TailwindRangeSteps

A five-step text size control with labels under the track and a live preview. aria-valuetext gives screen readers a word such as Medium instead of the raw number, and the labels underneath are hidden from them to avoid repetition.

View code
<div class="w-full max-w-xs">
  <label for="twrs4" class="text-sm font-semibold text-slate-800">Text size</label>
  <input id="twrs4" type="range" min="0" max="4" step="1" value="2" aria-valuetext="Medium" class="mt-2 w-full accent-rose-600">
  <div aria-hidden="true" class="mt-1 flex justify-between px-0.5 text-xs font-medium text-slate-600"><span>XS</span><span>S</span><span>M</span><span>L</span><span>XL</span></div>
  <p id="twrs4p" class="mt-3 rounded-lg bg-white p-3 text-slate-800 shadow-sm" style="font-size:16px">The quick brown fox.</p>
</div>
var r = document.getElementById('twrs4'), p = document.getElementById('twrs4p'), n = ['Extra small', 'Small', 'Medium', 'Large', 'Extra large'], s = [12, 14, 16, 19, 22];
r.oninput = function () { r.setAttribute('aria-valuetext', n[r.value]); p.style.fontSize = s[r.value] + 'px'; };

05. Tailwind Dual-Handle Price Range

TailwindRangeDual

A minimum and maximum price picker made of two native range inputs laid on top of each other. The inputs ignore the pointer except on their thumbs, a script keeps the two handles from crossing, and each one has its own accessible name.

View code
<fieldset class="w-full max-w-xs">
  <legend class="text-sm font-semibold text-slate-800">Price range</legend>
  <div class="relative mt-4 h-5">
    <div class="absolute inset-x-0 top-1/2 h-1.5 -translate-y-1/2 rounded-full bg-slate-300"></div>
    <div id="twrs5f" class="absolute top-1/2 h-1.5 -translate-y-1/2 rounded-full bg-indigo-600" style="left:20%;right:30%"></div>
    <input id="twrs5a" type="range" min="0" max="500" step="10" value="100" aria-label="Minimum price" class="pointer-events-none absolute inset-0 h-5 w-full appearance-none bg-transparent focus:outline-none [&::-moz-range-thumb]:pointer-events-auto [&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-indigo-600 [&::-moz-range-thumb]:bg-white [&::-moz-range-track]:bg-transparent [&::-webkit-slider-thumb]:pointer-events-auto [&::-webkit-slider-thumb]:size-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-indigo-600 [&::-webkit-slider-thumb]:bg-white [&:focus-visible::-moz-range-thumb]:[box-shadow:0_0_0_4px_#a5b4fc] [&:focus-visible::-webkit-slider-thumb]:[box-shadow:0_0_0_4px_#a5b4fc]">
    <input id="twrs5b" type="range" min="0" max="500" step="10" value="350" aria-label="Maximum price" class="pointer-events-none absolute inset-0 h-5 w-full appearance-none bg-transparent focus:outline-none [&::-moz-range-thumb]:pointer-events-auto [&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-indigo-600 [&::-moz-range-thumb]:bg-white [&::-moz-range-track]:bg-transparent [&::-webkit-slider-thumb]:pointer-events-auto [&::-webkit-slider-thumb]:size-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-indigo-600 [&::-webkit-slider-thumb]:bg-white [&:focus-visible::-moz-range-thumb]:[box-shadow:0_0_0_4px_#a5b4fc] [&:focus-visible::-webkit-slider-thumb]:[box-shadow:0_0_0_4px_#a5b4fc]">
  </div>
  <p class="mt-3 text-sm text-slate-700"><output id="twrs5o">$100 – $350</output></p>
</fieldset>
var a = document.getElementById('twrs5a'), b = document.getElementById('twrs5b'), f = document.getElementById('twrs5f'), o = document.getElementById('twrs5o');
function u(e) { if (+a.value > +b.value - 10) { if (e && e.target === a) a.value = b.value - 10; else b.value = +a.value + 10; } f.style.left = a.value / 5 + '%'; f.style.right = 100 - b.value / 5 + '%'; o.textContent = '$' + a.value + ' – $' + b.value; }
a.oninput = b.oninput = u; u();

06. Tailwind Slider with Step Buttons

TailwindRangeButtons

A thermostat-style control pairing a slider with minus and plus buttons, which are easier than dragging on a phone. The buttons call stepDown and stepUp on the input, so the slider remains the single source of truth.

View code
<div class="flex w-full max-w-xs items-center gap-3 rounded-2xl bg-slate-800 p-4">
  <button type="button" data-step="-1" aria-label="Decrease temperature" class="grid size-10 shrink-0 place-items-center rounded-full bg-slate-600 text-xl font-bold text-white hover:bg-slate-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-orange-300">−</button>
  <div class="min-w-0 flex-1">
    <div class="flex justify-between text-xs font-semibold text-slate-300"><label for="twrs6">Temperature</label><output id="twrs6o" for="twrs6">21°C</output></div>
    <input id="twrs6" type="range" min="10" max="30" value="21" class="mt-2 w-full accent-orange-500">
  </div>
  <button type="button" data-step="1" aria-label="Increase temperature" class="grid size-10 shrink-0 place-items-center rounded-full bg-slate-600 text-xl font-bold text-white hover:bg-slate-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-orange-300">+</button>
</div>
var r = document.getElementById('twrs6'), o = document.getElementById('twrs6o');
function u() { o.textContent = r.value + '°C'; }
r.oninput = u;
document.querySelectorAll('[data-step]').forEach(function (b) { b.onclick = function () { if (b.dataset.step > 0) r.stepUp(); else r.stepDown(); u(); }; });

About these Tailwind Range Sliders

Start with accent-color

accent-indigo-600 recolours the browser's own slider in one class and keeps native touch and keyboard behaviour.

Style the thumb with arbitrary variants

[&::-webkit-slider-thumb]: and [&::-moz-range-thumb]: reach the thumb pseudo-elements; add appearance-none to the input and the WebKit thumb first.

Fill the track

Write the value as a percentage into a custom property and draw the track with a hard-stop gradient in an arbitrary [background:…] utility.

Name every handle

A dual range is two inputs, so each needs its own label, here with aria-label. Use aria-valuetext when the number alone means little.

Frequently asked questions

Can I use these with keyboard?

Yes. Arrow keys, Page Up and Page Down, Home and End all work, because these are native inputs.

Why does the dual slider need JavaScript?

To stop the two handles crossing and to move the filled segment.

Is there a CSS version?

Yes, see the CSS range sliders collection.