Star-Rating Drag Slider — HTML CSS JS Snippet

Star-Rating Drag Slider · Forms · Plain HTML, CSS & JS · Live preview

What's included

Features

A genuine continuous slider, not five separate all-or-nothing star buttons
Two stacked, identically-styled star rows — one clipped by percentage width — produce a real fractional fill
Snaps to the nearest half-star during drag, giving 10 clean addressable positions on a 5-star scale
Click-anywhere-to-jump plus true drag, unified across pointer and touch input
Full keyboard support with half-star steps, plus Home/End for the extremes
A live numeric readout stays in sync with the visual fill from the same underlying value

About this UI Snippet

Star-Rating Drag Slider — A Slider Dressed as Stars, Not Five Separate Buttons

Screenshot of the Star-Rating Drag Slider snippet rendered live

A typical star rating is five separate clickable icons, each an all-or-nothing button. This is structurally a completely different thing: it's a single continuous slider — the exact same "drag anywhere, get a proportional value" mechanic as a volume control — that happens to render its fill using the star glyph instead of a plain colored bar.

Two identical star rows, one clipped

The trick is two stacked copies of ★★★★★: a gray "background" row showing all five empty stars, and an amber "fill" row directly on top of it, clipped with width: X% and overflow: hidden. Because both rows use identical text, font-size, and letter-spacing, clipping the top row at, say, 70% width doesn't just show 3.5 stars-worth of *characters* — it shows exactly 3.5 stars-worth of the same continuous strip, including a partially-visible fifth character if the value lands mid-star. That's a genuinely continuous fill using only two <div>s, no per-star DOM elements or SVG paths at all.

Half-star snapping, not five discrete zones

Dragging converts a pointer's x-position into a raw 0–5 value, then rounds it to the nearest 0.5 with Math.round(raw * 2) / 2 — giving 10 addressable positions (0, 0.5, 1, 1.5 … 5) instead of the usual 5-button rating's binary all-or-nothing stars, while still reading as a clean, deliberate rating rather than an arbitrary decimal.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly how stacking two identical star-character rows and clipping the top one by percentage width produces a genuinely fractional (not just per-star) fill effect, and why the font-size and letter-spacing of both rows must match exactly for it to align correctly. It's also worth asking the assistant to add a read-only display mode for showing an existing average rating without drag/keyboard interaction, or to add a hover preview that shows what rating would be set before the user actually clicks or drags.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a star-rating input that behaves as a genuine continuous drag slider rather than five separate clickable star buttons, in plain HTML, CSS, and vanilla JavaScript — no library.

Requirements:
- Two stacked, identically-styled rows of star characters occupying the exact same position — a background row showing all stars in a neutral/empty color, and a foreground "fill" row in an accent color, clipped to a percentage width via overflow hidden so only a fraction of it is visible.
- A single numeric rating value (out of a configurable maximum, e.g. 5) that drives the fill row's clipped width as a direct percentage, so partial values produce a genuinely partial star showing at the clip boundary, not just fully-lit or fully-empty individual stars.
- Dragging anywhere across the star row (via pointer events with a touch fallback) must convert the pointer's horizontal position within the row into a raw fractional rating, then snap that raw value to the nearest half-star increment before applying it — both during the drag itself (live snapping, not only on release) and it must also support a simple click-to-jump without requiring a drag gesture first.
- A small handle or marker indicating the current fill boundary position, purely visual, following the fill percentage.
- A live text readout showing the current numeric rating (e.g. "3.5 / 5") that stays in sync with the visual fill at all times.
- Keyboard support: the control must be focusable and respond to Left/Right (or Down/Up) arrow keys by adjusting the rating by one half-star increment, with Home and End jumping to the minimum and maximum respectively.
- The control must carry correct ARIA slider role and value attributes reflecting the current rating.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

<div class="srd-wrap">
  <div class="srd-track" id="srdTrack" tabindex="0" role="slider" aria-label="Rating" aria-valuemin="0" aria-valuemax="5" aria-valuenow="3.5">
    <div class="srd-stars-back">★★★★★</div>
    <div class="srd-stars-fill" id="srdFill">★★★★★</div>
    <div class="srd-handle" id="srdHandle"></div>
  </div>
  <div class="srd-readout" id="srdReadout">3.5 / 5</div>
</div>

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA star row appears with 3.5 stars filled and "3.5 / 5" shown below it.
  2. 2
    Drag across the starsThe fill follows your cursor continuously, snapping to the nearest half-star as you move.
  3. 3
    Click anywhere on the rowJump straight to that rating without needing to drag from the start.
  4. 4
    Use the keyboardFocus the row and press Left/Right (or Up/Down) to adjust by half a star; Home/End jump to 0 or 5.
  5. 5
    Change the scaleAdjust MAX in the JS for a 10-star or 3-star scale — the star string and math scale together.

Real-world uses

Common Use Cases

Product or service review forms
Let a reviewer express precision (like 3.5 stars) that a 5-button rating physically cannot represent.
Feedback and satisfaction surveys
A tactile, continuous alternative to a plain 1-5 radio button group.
Content or difficulty rating on cards
Read-only or interactive rating display that matches a site's existing star iconography exactly.
Admin tools for curating or scoring content
Fast, precise scoring input for internal moderation or curation dashboards.

Got questions?

Frequently Asked Questions

Remove the pointerdown/touchstart listeners and the tabindex/keydown handling, and just call render() once with a fixed value — the two-layer clipped star technique works identically as a static display.

Change the snapping formula from Math.round(raw * 2) / 2 (halves) to Math.round(raw * 4) / 4 (quarters) — the multiplier and divisor both control the snap granularity together.

It's the simplest possible technique requiring no icon library or SVG path data — as long as both rows render the exact same characters at the exact same size, clipping one by width produces a pixel-accurate fractional fill for free.

Yes — replace ★ with any character or emoji in both the background and fill rows; the clipping technique is symbol-agnostic as long as both rows stay identical.

The track carries role="slider" with aria-valuemin/max/now kept in sync, and is fully operable via Left/Right/Up/Down/Home/End without a mouse — pair it with a visible or aria-describedby label identifying what is being rated.