목차11개 항목
출처와 참고
mytory의 「더 나은 폼을 만드는 몇 가지 팁」(2024.02)을 요약·재구성한 노트다. 「묻는 것을 줄이고 짧게 쓴다」와 「폼을 시험하고 측정한다」는 web.dev의 「Learn Forms」 강좌 중 「Design basics」, 「Test your forms」, 「How to test forms for usability」, 「Test forms across devices and platforms」, 「Gathering data」 모듈을 바탕으로 보강했다.
폼 사용성이 중요한 이유
사용자는 웹에서 대부분 읽기만 하고, 직접 입력하는 순간은 폼뿐이다. 그래서 폼이 불편하면 사이트 전체의 인상이 나빠진다. 좋은 폼의 조건은 하나다. 사용자의 통제권을 빼앗지 않는다.
1. 묻는 것을 줄이고 짧게 쓴다
가장 빨리 끝나는 칸은 없는 칸이다. 칸마다 「이 값이 정말 필요한가, 지금 필요한가」를 묻는다. 칸이 줄면 이탈률과 개인 정보 위험이 함께 준다. 이미 받은 값은 다시 묻지 않고, 브라우저가 채울 수 있게 autocomplete를 단다(자동 완성과 autocomplete 토큰).
| 원칙 | 방법 |
|---|---|
| 라벨부터 쓴다 | 칸을 만들 때 <label>을 먼저 쓰면 무엇을 받는지가 분명해진다. placeholder는 라벨이 아니다(접근 가능한 폼과 오류 처리) |
| 라벨은 짧게 | 「이메일 주소를 입력하세요」보다 「이메일 주소」. 훑어 읽기 쉽다 |
| 라벨은 칸 위에 | 화면 폭과 상관없이 같은 모양이고 시선이 한 줄로 내려간다 |
| 한 열로 배치 | 여러 열은 읽는 순서를 흐리고 작성을 늦춘다 |
| 알맞은 요소 | 여러 줄은 <textarea>, 약관 동의는 체크박스. 값에 맞는 type을 고른다(HTML 입력 요소 치트시트) |
| 형식은 미리 알린다 | 「8자 이상」 같은 규칙은 제출 전에 칸 아래에 보인다 |
| 필수·선택 표시 | 대부분이 필수라면 필수 대신 「(선택)」을 표시하는 편이 깔끔하다 |
| 하나의 값은 한 칸 | 이름, 전화번호, 카드 번호를 여러 칸으로 쪼개지 않는다 |
| 조건부 칸 | 「기타」를 골랐을 때만 필요한 칸은 그때 보여 준다. 스크립트가 없어도 제출에는 문제없게 만든다 |
크기·테두리·탭 영역 같은 시각 기준은 폼 스타일링에 있다. 로그인·결제·주소처럼 유형이 정해진 폼은 로그인·가입 폼과 인증 입력, 결제·주소 폼을 따른다.
2. 브라우저 기본 동작을 지킨다
| 기본 동작 | 깨지는 흔한 원인 |
|---|---|
| 입력 칸에서 Enter로 제출 | <form> 없이 div와 클릭 핸들러로 폼을 만듦 |
| Tab·방향키로 이동 | 커스텀 컴포넌트가 포커스를 받지 못함 |
| 뒤로 가기 | 사용자는 이미 이 버튼으로 취소한다 |
취소 버튼은 두지 않는다. 제출 버튼 옆에 있으면 잘못 눌러 입력을 날리기 쉽고, 취소는 뒤로 가기가 이미 해 준다.
3. 모바일 가상 키보드를 맞춘다
inputmode로 칸마다 알맞은 키보드를 띄운다. 숫자 칸에 문자 키보드가 뜨면 사이트가 허술해 보인다.
| 속성 | 하는 일 |
|---|---|
type | 데이터 형식을 정하고 브라우저 검증까지 켠다 |
inputmode | 키보드 모양만 바꾼다 (numeric, decimal, tel, email, url, search) |
검증을 JavaScript로 직접 한다면 inputmode만 쓰는 편이 간섭이 적다.
| 값의 성격 | 선택 |
|---|---|
| 수량·순서처럼 크기가 의미 있고 방향키 증감이 유용 | type="number" |
| 전화번호 | type="tel". 전화 키패드와 연락처 자동 완성이 붙는다 |
| 카드 번호·인증 코드·주민번호처럼 숫자로 된 식별자 | type="text" inputmode="numeric" |
inputmode의 값 8가지는 HTML 입력 요소 치트시트에 있다.
수량 1처럼 기본값이 든 칸은 포커스 때 값을 전체 선택해 두면 바로 덮어쓸 수 있다. 모바일에서 특히 편하다.
input.addEventListener('focus', (e) => e.target.select());4. 검증 메시지는 보이게
아무 말 없이 제출이 안 되는 폼이 가장 나쁘다. 무엇이 틀렸는지 알려 주고, 가능하면 해당 칸으로 포커스를 옮긴다.
- HTML 기본 검증 팝업은 놓치기 쉽다. 문구는
setCustomValidity()로 바꾸고,:user-invalid로 오류 칸을 눈에 띄게 꾸민다. 팝업이 안 뜨는 상황도 있으니 여러 환경에서 확인한다. 속성과 API는 제약 검증: required·pattern·ValidityState에 있다. - 입력 중에 바로 오류를 띄우지 않는 타이밍(처음엔
blur·change, 한 뒤에는 실시간 갱신)은 제약 검증에 정리했다. VeeValidate의 검증 모드가 이런 방식이다. - 검증 라이브러리는 복잡한 UI에 빠르지만, 규칙이 특이하면 평범한
if문이 개발자와 사용자 모두에게 더 명확할 수 있다.
input:user-invalid {
border-color: crimson;
}5. 커서와 포커스를 빼앗지 않는다
| 하지 말 것 | 문제 | 대안 |
|---|---|---|
alert() 후 오류 칸으로 강제 포커스 | 포커스를 뺏고, 반복되면 사용자가 칸에 갇힌다 | 칸 옆에 인라인 메시지 |
| 입력 칸에 천 단위 쉼표를 직접 삽입 | 커서가 끝으로 튀고, NaN·앞자리 0 사라짐 같은 버그 | 입력은 그대로 두고 옆에 서식 붙은 값을 따로 표시 |
| 전화번호 하이픈 자동 삽입 | 백스페이스·방향키가 꼬인다 | 자유롭게 입력받고 하이픈은 서버에서 정리 |
| 전화번호를 칸 3개로 나누기 | 클릭·이동만 늘어난다 | 한 칸으로 받기 |
6. 시험하고 측정한다
자동 도구가 잡는 문제는 일부다. 폼은 기기, 사람, 데이터 세 방향으로 시험한다.
기기와 환경
| 확인 | 방법 |
|---|---|
| 키보드만으로 | Tab으로 끝까지 채우고 제출한다. 지금 어느 칸에 있는지 늘 보이는가, Tab 순서가 보이는 순서와 같은가 |
| 터치 | 실제 휴대폰에서 칸을 한 번에 누를 수 있는가, 맞는 가상 키보드가 뜨는가, 키보드나 툴바가 제출 버튼을 가리지 않는가 |
| 보조 기술 | 스크린 리더(VoiceOver, NVDA), 200% 확대, DevTools의 시각 결함 에뮬레이션(스크린 리더로 테스트하기) |
| 여러 브라우저·기기 | 오래된 노트북, 빌린 태블릿까지. 원격 기기 테스트 서비스도 있다 |
| 현실 조건 | 햇빛 아래 대비, 느린 네트워크(DevTools 네트워크 제한), 걸으면서 한 손으로, 시간에 쫓기며 |
| 다양한 데이터 | 다른 나라 주소, 비라틴 이름, 아주 긴 값 |
Lighthouse는 라벨 없는 칸, 너무 작은 탭 영역과 글자를 잡고, axe·WAVE 같은 접근성 도구는 라벨 연결과 대비를 검사한다(접근성 평가 방법과 도구).
사람으로 시험하기: 사용성 테스트
flowchart LR a["과제를 준다<br/>#quot;홈에서 문의 폼을 찾아 보내 본다#quot;"] --> b["지켜본다<br/>옆에 앉거나 화면을 공유한다. 돕지 않는다"] b --> c["소리 내어 말하게<br/>지금 무엇을 하는지, 어디서 막히는지"] c --> d["묻는다<br/>무엇을 채울지 분명했나, 헷갈린 곳은 어디였나"] d --> e["고친다"] e -->|"같은 사람, 같은 과제로 다시"| a
- 실험실이나 거창한 보고서는 필요 없다. 한 명이라도 도움이 되고, 두 명 이상이면 더 낫다. 나이와 기술 경험이 다양할수록 좋다.
- 영구적 장애만이 아니라 일시적(팔을 다쳐 한 손), 상황적(눈부신 햇빛) 제약도 떠올린다.
데이터로 측정하기
| 대상 | 보는 것 |
|---|---|
| 페이지 | 폼 페이지의 방문 수, 이탈률, 나간 비율. 이탈률이 높으면 폼이 복잡하거나 무엇을 넣을지 모르는 것이다 |
| 목표 퍼널 | 「폼 열기 → 이름 입력 → 우편번호 입력 → 제출 → 다음 페이지」처럼 단계를 정해 어디서 떨어지는지 본다 |
| 이벤트 | 특정 칸 입력, 제출 버튼 클릭, 서버 검증 실패. 몇 개로 시작해 필요할 때만 늘린다 |
| 성능 | 실사용자 데이터(RUM)와 실험실 데이터. 폼 페이지의 로딩·응답·레이아웃 이동(웹 성능 지표와 Lighthouse) |
| 알림 | 폼 페이지 트래픽 급감, 이탈률 급증 |
바꾸기 전과 후를 같은 기준으로 잰다. 목표를 정하고 → 재고 → 분석하고 → 고치고 → 며칠 뒤 다시 잰다. 두 디자인을 무작위로 나눠 보여 주는 A/B 테스트로 비교할 수도 있다. 측정 역시 개인 정보이므로 필요한 만큼만 모으고 동의를 받는다.
정리
- 폼 품질은 작은 디테일의 합이고, 하나하나는 어렵지 않다.
- 기준은 사용자의 통제권이다. 말 없이 막기, 포커스 뺏기, 커서 옮기기, 입력 제한은 모두 사용성을 깎는다.
- 모바일에서는
inputmode한 줄이 체감 품질을 크게 바꾼다. - 칸을 줄이고, 라벨은 짧게 위에, 한 열로. 그리고 실제 기기와 실제 사람으로 시험하고 데이터로 확인한다.
관련 노트: HTML 입력 요소 치트시트, 폼 스타일링, 제약 검증: required·pattern·ValidityState, 폼 제출과 데이터 전송, 접근 가능한 폼과 오류 처리, HTML 기초와 HTML5, 폼과 제어 컴포넌트, 브라우저 기본 동작을 존중하기, 폼 컨트롤과 포커스 이벤트, 모바일 앱 UI 가이드라인