Number input

숫자 입력

A field for one numeric value, paired with −/+ buttons that step it by a fixed amount, with direct typing too.

Also known as: SpinbuttonQuantity inputNumeric stepper
···
html
<div class="niw">
  <span class="nilabel">수량</span>
  <div class="nigroup" role="group" aria-label="수량 선택">
    <button class="nibtn" id="nidn" aria-label="1 감소">−</button>
    <input class="niinput" id="nival" type="text" inputmode="numeric" role="spinbutton" aria-valuenow="4" aria-valuemin="1" aria-valuemax="10" aria-label="수량" value="4">
    <button class="nibtn" id="niup" aria-label="1 증가">+</button>
  </div>
</div>
css
.niw{position:absolute;inset:0;display:grid;place-items:center;gap:8px}
.nilabel{color:var(--muted);font-size:10px}
.nigroup{display:flex;align-items:stretch;border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--surface)}
.nibtn{width:34px;border:0;background:var(--bg);color:var(--fg);font-size:16px;cursor:default;display:grid;place-items:center}
.nibtn:disabled{opacity:.35}
.niinput{width:44px;border:0;border-left:1px solid var(--line);border-right:1px solid var(--line);text-align:center;font-size:14px;font-weight:700;color:var(--fg);background:var(--surface)}
js
const val = document.getElementById('nival'), dn = document.getElementById('nidn'), up = document.getElementById('niup');
let n = 4;
function paint() { val.value = String(n); val.setAttribute('aria-valuenow', String(n)); dn.disabled = n <= 1; up.disabled = n >= 10; }
function step(delta) { n = Math.min(10, Math.max(1, n + delta)); paint(); }
let auto = true, dir = 1;
dn.addEventListener('click', () => { auto = false; step(-1); });
up.addEventListener('click', () => { auto = false; step(1); });
paint();
setInterval(() => {
  if (!auto) return;
  if (n >= 10) dir = -1;
  if (n <= 1) dir = 1;
  step(dir);
}, 700);

A native <input type="number"> gets spinner buttons and validation from the browser for free. Building one by hand means giving the field role="spinbutton" plus aria-valuenow/aria-valuemin/aria-valuemax, so a screen reader can announce the current value and its range.

Two name collisions are easy to fall into. A slider suits picking an approximate value fast, by dragging across a wide range, while a number input suits a precise, already-known value handled one unit at a time — "4 of an item in a cart." And the "stepper" entry elsewhere in this dictionary is an unrelated component that only shares the everyday word "stepper" — that one shows progress through named stages ("Shipping → Payment → Done"), while this one just raises or lowers a single quantity.

Holding a button down to repeat-increment rapidly is common too, but the final value should still stay clamped within min/max.