숫자 입력

Number input

값 하나를 1단위(또는 정해진 step)로 늘리고 줄이는 −/+ 버튼과 직접 타이핑도 되는 입력창.

다른 이름: 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);

네이티브 <input type="number">를 쓰면 스피너 버튼과 검증을 브라우저가 대신 해주고, 커스텀으로 만든다면 입력창에 role="spinbutton"과 aria-valuenow/aria-valuemin/aria-valuemax를 둬서 지금 값과 범위를 스크린리더가 읽게 합니다.

이름이 겹쳐 헷갈리기 쉬운 게 두 가지 있습니다. 슬라이더는 넓은 범위에서 대략적인 값을 드래그로 빠르게 고르는 데 적합하지만, 숫자 입력은 "장바구니 수량 4개"처럼 이미 아는 정확한 값을 한 단위씩 다루는 데 적합합니다. 그리고 이 사전의 다른 항목인 "스테퍼"(위저드 단계 표시기)와는 한국어 명칭만 겹칠 뿐 전혀 다른 컴포넌트입니다 — 그쪽은 "배송지 → 결제 → 완료" 같은 진행 단계를 보여주고, 이 숫자 입력은 하나의 수량 값을 늘리고 줄일 뿐입니다.

버튼을 길게 누르고 있으면 빠르게 연속 증가하는 것도 흔한 패턴이지만, 그 경우에도 최종 값은 항상 min/max 안에 갇혀야 합니다.