숫자 입력 및 스테퍼 시스템은(는) 무엇을 하나요?
목적
숫자 입력 및 스테퍼 시스템은 이산적인 숫자 값을 선택, 조정 또는 입력하는 컨트롤을 설계, 구조화 및 구현하기 위한 표준화된 프레임워크를 제공합니다. 장바구니 품목 수량, SaaS 시트 할당, 가격 계층 단위, 예산 범위 또는 치수 사양과 같은 정확한 숫자 입력은 빠른 미세 조정과 직접 텍스트 편집, 명확한 최소/최대 경계 상태, 터치 친화적인 탭 대상, 전체 키보드 및 화면 판독기 접근성 간의 균형을 요구합니다.
표준 HTML <input type="number"> 컨트롤은 브라우저마다 일관되지 않게 렌더링되며, 종종 터치 대상 가이드라인(WCAG 2.2 SC 2.5.8)을 위반하고 실수로 스크롤 조정을 트리거하는 작고 사용자 정의가 불가능한 네이티브 스피너 화살표를 제공합니다. 이 스킬은 사용자 정의 숫자 스테퍼 및 단위 바운드 필드에 대한 명시적 UI 패턴, 공간 레이아웃 규칙, 상호작용 상태 및 접근성 표준을 정의합니다.
사용 사례
- E-커머스 장바구니 수량 선택기: 쇼핑객이 PDP, 장바구니 서랍 및 체크아웃 요약 테이블 내에서 제품 품목 수량을 쉽게 증가, 감소 또는 입력할 수 있도록 합니다.
- SaaS 플랜 시트 및 라이선스 컨트롤: 가격 페이지 또는 구독 관리 설정에서 사용자 시트, 서버 인스턴스 또는 스토리지 기가바이트를 프로비저닝합니다.
- 양식 바운드 단위 입력: 백분율 값(0–100%), 연령 제한, 품목 치수(길이/너비/높이) 또는 통화 금액과 같은 제약된 메트릭을 캡처합니다.
- 재무 및 계산기 컨트롤: 대화형 계산기 내에서 대출 기간, 입금액 또는 투자 증분을 선택합니다.
- 대시보드 및 필터 컨트롤: 데이터 밀도가 높은 데스크톱 환경에서 숫자 임계값, 페이지 매기기 행 제한 또는 메트릭 범위 필터를 조정합니다.
사용하지 말아야 할 경우
- 연속 범위 선택: 정확한 값보다 상대적 위치가 중요한 광범위하고 비특정적인 숫자 범위 탐색의 경우
accessible-range-slider-implementation또는 이중 엄지 슬라이더를 대신 사용하십시오. - 큰 임의의 숫자: 신용 카드 번호, 전화번호, 우편번호 또는 주민등록번호와 같이 증가/감소 연산이 의미가 없는 경우
form-design-system과 함께 표준<input type="text" inputmode="numeric">을 사용하십시오. - 날짜 및 시간 선택: 달력 날짜, 월 또는 시계 시간을 선택하려면
calendar-and-date-system을 사용하십시오. - 대량의 이산 옵션 집합: 사전 구성된 대량 수량(예: 25, 50, 100, 500) 중에서 선택할 때는
segmented-control-system또는custom-select-and-combobox-system을 사용하십시오.
입력
- 값 경계: 최소(
min), 최대(max) 및 단계 증분(step) 제약 조건. - 컨텍스트 및 밀도: 사용 가능한 레이아웃 공간(컴팩트 인라인 테이블 행 vs. 눈에 띄는 PDP 구매 블록).
- 입력 형식 및 단위: 관련 물리적 또는 통화 단위(예:
$,%,개,kg,좌석). - 상호작용 모드: 직접 수동 텍스트 입력이 허용되는지 또는 조정이 스테퍼 버튼으로만 제한되는지 여부.
- 브랜드 및 표면 토큰: 표면 배경, 활성 테두리, 비활성화 상태, 포커스 링 및 아이콘 글리프에 대한 팔레트 토큰.
출력
- 스테퍼 컴포넌트 사양: 감소 버튼, 숫자 표시/입력, 증가 버튼 및 단위 레이블을 정의하는 시각적 해부학.
- 경계 및 상태 매트릭스: 기본, 호버, 포커스, 비활성화(최소/최대 제한), 로딩 및 오류 상태에 대한 시각적 처리.
- 반응형 공간 레이아웃 사양: 중단점별 터치 대상 치수(터치용 최소 44x44px, 컴팩트 데스크톱용 24x24px), 간격 및 글꼴 메트릭.
- 접근성 및 키보드 매핑: ARIA 속성(
role="spinbutton",aria-valuenow,aria-valuemin,aria-valuemax), 라이브 리전 구성 및 키보드 단축키 핸들러 사양.
워크플로우
1. 스테퍼 변형 선택
컨텍스트 및 상호작용 의도에 따라 적절한 구조적 변형을 선택하십시오.
- 표준 가로 스테퍼(3피스 세그먼트): 왼쪽에 감소 버튼(
-), 중앙 텍스트 입력, 오른쪽에 증가 버튼(+). E-커머스 PDP, 장바구니 항목 및 SaaS 시트 카운터에 가장 적합합니다. - 컴팩트 인라인 스테퍼(스택 화살표): 텍스트 입력과 후행 측면에 세로로 쌓인 마이크로 버튼. 고밀도 데스크톱 데이터 테이블, 도구 모음 및 SaaS 설정 사이드바 패널에 가장 적합합니다.
- 단위 고정 입력: 고정된 접두사/접미사 단위 레이블(예:
$,USD,px,%)과 선택적 스테퍼 버튼이 있는 텍스트 필드. 재무 입력 및 시스템 구성 양식에 가장 적합합니다. - 독립형 버튼 카운터: 완전히 클릭 가능한 알약으로, 탭하면 인라인 모달/팝오버가 열리거나 포커스 시 활성 스테퍼로 변환됩니다.
2. 시각적 해부학 및 터치 대상 규칙 설정
명확한 기하학적 매개변수를 사용하여 컴포넌트를 구조화하십시오.
- 터치 대상 치수: 모든 대화형 증가/감소 버튼이 모바일/터치 인터페이스에서 최소 히트 대상 44x44px를 갖도록 하십시오(WCAG 2.5.5 / 2.5.8). 데스크톱 전용 컴팩트 UI에서는 적절한 히트 패딩과 함께 최소 24x24px를 유지하십시오.
- 입력 필드 크기 조정: 예상 최대 자릿수 길이에 따라 CSS
ch단위를 사용하여 동적으로 너비를 설정하십시오(예: 2자리 수량의 경우width: calc(3ch + 2rem)). - 타이포그래피 및 정렬: 입력 필드 내에서 숫자 값을 가운데 정렬하십시오. 빠른 값 전환 중 레이아웃 변경을 방지하려면 표 모노스페이스 숫자(
font-variant-numeric: tabular-nums;)를 사용하십시오. - 시각적 그룹화: 통합된 기능을 신호하기 위해 버튼과 입력을 공유 테두리 컨테이너 또는 연속적인 세그먼트된 알약 내에 포함시키십시오.
3. 경계 동작 및 비활성화 상태 정의
사용자 불만을 방지하기 위해 최소 및 최대 제한을 명확하게 전달하십시오.
- 최소 경계에서 (
value <= min):- 감소 버튼 비활성화(
disabled속성 및aria-disabled="true"). - 낮은 대비 비활성화 스타일 적용(예:
opacity: 0.4; cursor: not-allowed;). - E-커머스 장바구니 컨텍스트에서
min === 1인 경우, 값이 1일 때 감소 버튼을 선택적으로 "휴지통/삭제" 아이콘으로 변환하여 라인 항목 제거를 허용합니다.
- 감소 버튼 비활성화(
- 최대 경계에서 (
value >= max):- 증가 버튼 비활성화(
disabled속성 및aria-disabled="true"). - 사용자가 더 증가시키려고 하면 인라인 도우미 텍스트(예: "주문당 최대 10개") 또는 미묘한 도구 설명을 제공합니다.
- 증가 버튼 비활성화(
- 직접 입력 유효성 검사:
- 입력
blur시, 범위를 벗어난 입력 값을 가장 가까운 유효한 제한으로 자동 클램핑합니다(예: 최대 10 필드에99를 입력하면10으로 클램핑). - 단계 증분이 정수가 아닌 경우(예:
step="0.5"), blur 시 입력된 값을 가장 가까운 유효한 단계 증분으로 반올림합니다.
- 입력
4. 키보드 탐색 및 터치 피드백 구현
입력 장치 간 원활한 제어를 보장하십시오.
- 키 바인딩:
ArrowUp/ArrowRight:step만큼 값 증가.ArrowDown/ArrowLeft:step만큼 값 감소.PageUp:step * 10(또는 더 큰 단계 델타)만큼 값 증가.PageDown:step * 10만큼 값 감소.Home: 값을min으로 설정(정의된 경우).End: 값을max로 설정(정의된 경우).
- 누르고 있기 자동 반복: 사용자가 증가/감소 버튼(포인터 또는 키보드 사용)을 누르고 있으면, 500ms 초기 지연 후 값 자동 반복을 시작하고 100ms마다 순환합니다.
- 터치/모바일 키보드:
<input>요소에inputmode="numeric"또는inputmode="decimal"및pattern="[0-9]*"를 설정하여 표준 네이티브 브라우저 스피너를 강제하지 않고 모바일 장치에서 숫자 키패드를 트리거합니다.
5. 접근성 및 화면 판독기 의미 구성
WCAG 2.1 / 2.2 AA 준수 경험을 제공하십시오.
- 시맨틱 HTML 옵션:
- 옵션 A(스테퍼 버튼이 있는 네이티브 입력): 명시적
<label>과 연결된<input type="text" inputmode="numeric">을 사용하십시오. 감소/증가 버튼에<button type="button" aria-label="수량 감소">및aria-controls="input-id"로 강조 표시하십시오. - 옵션 B(ARIA Spinbutton 역할): 컨테이너 또는 입력에
role="spinbutton",aria-valuenow="3",aria-valuemin="1",aria-valuemax="10",aria-valuetext="3석"및aria-label="좌석 수 선택"을 적용하십시오.
- 옵션 A(스테퍼 버튼이 있는 네이티브 입력): 명시적
- 포커스 링 관리: 활성 버튼 및 텍스트 입력 주변에 가시적이고 고대비인 포커스 링(
outline: 2px solid var(--focus-ring); outline-offset: 2px;)을 유지하십시오. 포커스 링은 부모 컨테이너 경계에 의해 숨겨지거나 잘려서는 안 됩니다. - 라이브 리전 알림:
aria-live="polite"를 사용하거나aria-valuenow를 동적으로 업데이트하여 보조 기술이 버튼 누름 시 값 변경을 즉시 알리도록 하십시오.
결정 규칙
컴포넌트 패턴 매트릭스
| 사용 사례 | 권장 변형 | 버튼 배치 | 최소/최대 전략 |
|---|---|---|---|
| E-커머스 PDP | 표준 가로 | 양쪽 배치(- 왼쪽, + 오른쪽) | 최소 = 1(또는 1에서 휴지통), 최대 = 재고 제한 |
| 장바구니 라인 항목 | 컴팩트 가로 / 휴지통 혼합 | 양쪽 배치(-/휴지통 왼쪽, + 오른쪽) | 최소 = 0(항목 제거), 최대 = 사용 가능한 재고 |
| SaaS 청구 시트 | 단위 접미사가 있는 가로 | 양쪽 배치(- 왼쪽, + 오른쪽) | 최소 = 최소 플랜 계층, 최대 = 계정 한도 |
| 데스크톱 데이터 테이블 | 스택 인라인 스테퍼 | 후행 스택(▲ 위, ▼ 아래) | 최소/최대 blur 시 클램프 |
| 금융 금액 | 단위 고정 입력($) | 선택적 양쪽 배치 또는 수동 전용 | 최소 = 0, 최대 = 제한 및 유효성 검사 메시지 |
직접 입력 대 버튼 전용 규칙
- 직접 입력 허용(기본값): 수량이 5보다 크거나 사용자가 큰 숫자를 직접 입력할 수 있는 경우(예: 50개 항목 주문 또는 $500 예산 설정).
- 버튼 전용으로 제한(
readonly입력): 값 범위가 매우 작은 경우(예: 1~5)에만 해당하며, 작은 터치 장치에서 자유 형식 텍스트 입력이 불필요한 유효성 검사 오버헤드를 발생시킵니다.
제약 조건
- 접근성 (WCAG 2.1 / 2.2 AA):
- 버튼은 동작을 설명하는 명시적
aria-label속성을 제공해야 합니다(예: "품목 수량 감소"). - 증가 및 감소 버튼은 터치 뷰포트에서 최소 터치 대상 44x44px를 유지해야 합니다(SC 2.5.8).
- 활성 포커스 표시기는 WCAG 2.4.11(포커스 가려짐 없음) 및 SC 2.4.13(포커스 모양)을 충족해야 합니다.
- 버튼은 동작을 설명하는 명시적
- 숫자 형식:
- blur 시 입력에 빈 값 또는
NaN값이 남아 있도록 절대 허용하지 마십시오.min또는 이전 유효 값으로 대체하십시오. - 숫자는
font-variant-numeric: tabular-nums;를 사용하여 렌더링되어 증분 중 레이아웃 재배치를 방지해야 합니다.
- blur 시 입력에 빈 값 또는
- 모바일 소프트 키보드:
- iOS/Android에서 표준 숫자 키패드를 열려면 항상
inputmode="numeric"(또는decimal)을 설정하십시오. CSS(::-webkit-inner-spin-button)에서 네이티브 스피너를 비활성화하여 기본<input type="number">화살표 스타일을 피하십시오.
- iOS/Android에서 표준 숫자 키패드를 열려면 항상
일반적인 실패 패턴
- 작고 비표준적인 터치 대상: 모바일에서 18x18px 쉐브론 버튼을 사용하여 잘못된 탭과 사용자 불만을 유발합니다.
- 네이티브 브라우저
<input type="number">에 의존: 브라우저 기본 스피너가 일관성 없이 렌더링되고, 사용자 정의 텍스트 패딩과 겹치거나 의도하지 않은 스크롤 조정을 트리거하도록 허용합니다. - 경계 비활성화 신호 누락:
value === min일 때 감소 버튼을 시각적으로 활성 상태로 두어 사용자가 피드백 없이 클릭하게 합니다. - 클램프되지 않은 자유 형식 입력: 사용자가 유효하지 않은 값(예:
-5또는999999)을 blur 시 클램핑 또는 오류 피드백 없이 입력하도록 허용합니다. - 키보드 지원 누락:
Tab포커싱 가능성 및ArrowUp/ArrowDown이벤트 처리가 부족한 사용자 정의<div>버튼을 설계합니다.
검증 기준
- 감소 및 증가 버튼이 터치 뷰포트에서 최소 44x44px 터치 대상을 충족합니다.
- 표 모노스페이스 타이포그래피(
tabular-nums)가 업데이트 중 레이아웃 지터를 방지하는 데 사용됩니다. - 최소 및 최대 제한에서 각각의 버튼이 비활성화 상태(
aria-disabled="true")로 전환됩니다. - 모바일 입력이
inputmode="numeric"또는inputmode="decimal"을 사용합니다. - 컴포넌트가
ArrowUp,ArrowDown,PageUp,PageDown,Home및End키를 올바르게 처리합니다. - 프로그래매틱 레이블(
aria-label또는<label>) 및 ARIA 역할(role="spinbutton"또는 명시적aria-controls버튼)이 구성됩니다. - 범위를 벗어난 입력 값이
blur시 자동 클램프되거나 유효성 검사 오류 메시지를 트리거합니다. - 고대비 포커스 표시기가 보이고 가려지지 않습니다.