vs data-stepper vs for numeric and step-through inputs."> vs data-stepper vs for numeric and step-through inputs."> vs data-stepper vs for numeric and step-through inputs.">
Vanilla Breeze

Numeric Inputs — Decision Guide

When to use vs data-stepper vs for numeric and step-through inputs.

Three tiers of stepper-style input. Pick the lowest tier that does the job — the higher tiers cost more JS and only earn their weight when the lower one cannot reach the use case.

The decision table

Tier What it is Use when
<input type="number"> Native HTML element. UA-rendered spinner buttons, arrow-key step, min / max / step, form validation, numeric mobile keyboard. Plain numeric value and the default UA UI is acceptable.
<input type="number" data-stepper> VB upscale. Wraps the native input with custom +/- buttons, hides UA spinners, decimal-aware step math, min/max clamping with disabled-at-bounds. Plain numeric value, you want consistent VB-styled buttons across browsers.
<stepper-wc> Stepper for values the native number input cannot represent. Formatted units, currency, percent, time, byte sizes; token-snap design-system scales; discrete enums; long-press acceleration.

Decision rule: if <input type="number" data-stepper> works, use it. Reach for <stepper-wc> only when you hit a case the native input cannot represent.

Tier 1 — native <input type="number">

The browser primitive. Smallest payload, full form participation, validation, and a numeric soft-keyboard on mobile. The downside is the UA-rendered spinner buttons, which differ across browsers and are tiny for touch.

Reach for this when you do not need consistent buttons across browsers.

Tier 2 — data-stepper

VB's progressive upscale of <input type="number">. Wraps the input with VB-styled +/- buttons, hides the UA spinners, handles step math without floating-point drift, and disables the buttons at min / max. No new element — same form behaviour, same validation, same value semantics. See the data-stepper attribute reference for details.

This handles the bread-and-butter cases: cart quantity, settings inputs, scoring tools, basic numeric forms. If your value is a plain number, this is the right tier.

Tier 3 — <stepper-wc>

<stepper-wc> is for values the native number input cannot represent at all. Four cases:

  1. Formatted units$5.00, 12px, 50%, durations (15:00), byte sizes (2.05 KB). The native input rejects non-numeric characters, so locale-aware Intl.NumberFormat output and unit suffixes belong here.
  2. Token-snap scales — step through a curated list (data-values="0,4,8,12,16,24") instead of arithmetic. Useful for design-system spacing or type scales.
  3. Discrete enums — step through labeled options like S / M / L / XL or low / medium / high / critical. Not a number at all.
  4. Long-press acceleration — opt in via data-accelerate for large ranges where multiple taps would be tedious.

See the <stepper-wc> reference for the full attribute list, keyboard map, and event contract.

What if I need vertical, large, or compact steppers?

Those are visual variants of the same primitive, not different primitives. Add them to data-stepper first (e.g. data-stepper-orient="vertical", data-stepper-size="lg") so the cheaper tier benefits too. Don’t scaffold a new component for a CSS variant.

See also