Skip to content

Add Range plugin for track fill, value bubble, and tick marks#42525

Merged
mdo merged 8 commits into
v6-devfrom
mdo/customize-range-input
Jun 22, 2026
Merged

Add Range plugin for track fill, value bubble, and tick marks#42525
mdo merged 8 commits into
v6-devfrom
mdo/customize-range-input

Conversation

@mdo

@mdo mdo commented Jun 18, 2026

Copy link
Copy Markdown
Member

Summary

Adds an opt-in JavaScript plugin that enhances <input type="range">, building on the idea from #37499 and taking it further into a proper plugin.

A consistent cross-browser fill cannot be done with pseudo-elements alone — only Firefox has ::-moz-range-progress; WebKit/Blink have no equivalent and CSS can't read an input's value. So the plugin publishes the current value as a --bs-range-value custom property that the track gradient consumes.

Opt in per input with data-bs-range; plain .form-range inputs are completely unaffected.

Features

  • Fill — colored track up to the thumb, themeable via --range-fill-bg.
  • Value bubble (data-bs-bubble="true") — a floating value that tracks the thumb.
  • Tick marks (data-bs-ticks="true") — generated from a linked <datalist>, with labels from each <option>.

Options: bubble, ticks, formatter. Emits changed.bs.range.

Notes

  • The bubble and tick marks are siblings of the input, so they don't inherit the input's --range-fill-bg token. The plugin copies the input's resolved fill color onto them, and the CSS falls back to --primary-base, so they're never rendered blank. (This was the cause of an invisible bubble in early testing.)
  • input isn't in EventHandler's native-event list, so it can't be namespaced — it's bound raw and removed explicitly in dispose().
  • The input is intentionally not wrapped (wrapping would break validation's .form-range ~ .invalid-feedback); instead the parent gets a .range-anchored positioning class and decorations position from the input's offset box.

Test plan

  • New js/tests/unit/range.spec.js; full Karma suite passes (1113/1113).
  • Verified rendering in WebKit (Playwright) — fill, bubble, and ticks all render correctly.
  • ESLint, Stylelint, markdownlint, and Prettier all clean.

dist/ is intentionally not committed here; CI rebuilds it.

mdo added 6 commits June 20, 2026 22:02
Adds an opt-in JavaScript plugin (`data-bs-range`) that enhances
`<input type="range">`. A consistent cross-browser fill can't be done
with pseudo-elements alone (only Firefox has `::-moz-range-progress`),
so the plugin publishes the current value as a `--bs-range-value`
custom property that the track gradient consumes.

- Fill: colored track up to the thumb, themeable via `--range-fill-bg`
- Value bubble (`data-bs-bubble`): floating value that tracks the thumb
- Tick marks (`data-bs-ticks`): generated from a linked `<datalist>`

The bubble and ticks are siblings of the input, so they don't inherit
the input's `--range-fill-bg`; the plugin copies the resolved value onto
them and the CSS falls back to `--primary-base` so they're never blank.

Plain `.form-range` inputs are untouched. Includes unit tests and docs.
- Make `.form-range` the positioning context (`position: relative`) and
  drop the JS-added `.range-anchored` class; the bubble and ticks are
  siblings of the input, so they already share its offset parent.
- Rename `--range-fill-bg` to `--range-track-fill-bg` for accuracy.
- Keep SCSS custom properties unprefixed (the build adds `--bs-`) and
  have the plugin read/write the prefixed names, matching the codebase.
- Trim obvious comments.
Restructure range as an always-JS component so the fill, value bubble,
and tick marks are driven by a single `--bs-range-fill` ratio in CSS.

- `.form-range` is now a wrapper that owns the tokens; the input takes
  `.form-range-input`. Children inherit the tokens, so the old JS color
  copying and px positioning are gone.
- The plugin only sets `--bs-range-fill` (0–1) and the bubble text; the
  track gradient, bubble position, and tick positions are pure CSS calc.
  Drops `_thumbWidth`, `_inheritFillColor`, the resize listener, and the
  `.range-anchored` class.
- Value bubble reuses the tooltip markup/styles instead of duplicating a
  pill and arrow. Tick marks are generated from the linked `<datalist>`
  and positioned per-value (handles uneven values); tick coloring dropped.
- Auto-inits every `.form-range`; rename fill token to
  `--range-track-fill-bg`.
- Validation moves to `.form-range-input` with a `:has()` feedback toggle.
- Add the "New" badge to the Range sidebar item and document the breaking
  changes in the migration guide.
Build `grid-template-columns` from the gaps between the datalist values
so each tick lands on a grid line — this handles unevenly-spaced values
just like the old per-tick calc did, but keeps the ticks and their labels
in normal flow (the container sizes to fit the labels instead of them
overflowing an absolutely-positioned box). Inset by half the thumb so the
end ticks align with the thumb travel.

Also wraps the token map in the `custom-property-no-missing-var-function`
stylelint disable (matching _strength.scss). Includes the disabled-track
fill styling.
@mdo mdo force-pushed the mdo/customize-range-input branch from ce5ced2 to 88b7243 Compare June 21, 2026 05:05
@coliff

coliff commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

PREVIEW: https://deploy-preview-42525--twbs-bootstrap.netlify.app/docs/6.0/forms/range/

love it! Tested on Firefox (Windows), Edge (Windows), Chrome (Windows) and iPadOS 27 Beta.

The tick marks are very subtle though. I think they could do with being a bit taller and having more contrast.
tick mark contrast

Also wondering if tick mark positioning could be improved a bit - screenshot with element outline on:
tick mark positioning

@mdo

mdo commented Jun 21, 2026

Copy link
Copy Markdown
Member Author

Yeah some improvements to be made for sure. Agreed on height and alignment.

@mdo

mdo commented Jun 22, 2026

Copy link
Copy Markdown
Member Author

Should all be addressed!

@mdo mdo merged commit b5a6186 into v6-dev Jun 22, 2026
12 checks passed
@mdo mdo deleted the mdo/customize-range-input branch June 22, 2026 17:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Inbox

Development

Successfully merging this pull request may close these issues.

2 participants