unscripted/ui

Slider

input type=range with a styled track and thumb. Keyboard stepping, Home/End, form participation — all native.

scroll-driven

How it works

  • The <input> is a transparent 16px box (h-4 bg-transparent) holding the thumb; the visible track is the runnable-track pseudo (::-webkit-slider-runnable-track / ::-moz-range-track, both h-1.5 bg-secondary rounded-full). The thumb is styled twice ([&::-webkit-slider-thumb]: and [&::-moz-range-thumb]:) and each engine ignores the other’s selectors because every utility compiles to its own rule.
  • On WebKit the 16px thumb rides a 6px track, so [&::-webkit-slider-thumb]:-mt-[5px] recenters it ((16 − 6) / 2). Firefox aligns ::-moz-range-thumb with ::-moz-range-track automatically.
  • The fill is the load-bearing trick. Firefox fills the left of the track natively with [&::-moz-range-progress]:bg-primary. WebKit has no filled-track pseudo-element, so the fill is scroll-driven: the thumb exposes a view-timeline, the input reads it via timeline-scope, and an animation drives a registered --range-fill property that a linear-gradient paints onto the track — a pure function of thumb position, no JS or oninput. This block lives in a separate CSS file because @property and view-timeline have no utility form.

The fallback story

  • Without scroll-driven animations, @supports skips the block: WebKit/Chromium show a plain secondary track with no fill, Firefox still fills natively via ::-moz-range-progress. The slider stays fully usable — only the progress-style fill on WebKit is missing.

Browser support

Minimum stable version per engine, resolved at build time from MDN's browser-compat-data; Baseline status from the official web-features dataset. Everything degrades gracefully — the “when missing” column is the actual behavior, not a broken page.

FeatureChromeEdgeFirefoxSafariWhen missing
Scroll-driven animations (view-timeline / timeline-scope)Limited availability11611626WebKit/Chromium show a plain secondary track with no filled portion; Firefox still fills natively via ::-moz-range-progress. The slider stays fully usable — only the progress-style fill is missing.

† The badge tests animation-timeline as a stand-in — the range fill also needs view-timeline, timeline-scope and @property, which all shipped together with scroll-driven animations in every engine that has them.