본문으로 건너뛰기

버그 제보

이상한 점을 알려 주시면 고칠게요. 지금 보고 있는 페이지와 브라우저 정보가 함께 담겨요.

페이지:

Frontend

더 나은 폼을 만드는 팁

작성 2026. 10. 17.추가
목차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 가이드라인

원본 기록7

댓글

GitHub 계정으로 댓글을 남길 수 있어요.