폼
웹사이트에서 사람이 가장 많이 "일하는" 화면은 폼이다. 모임을 신청하고, 주소를 적고, 비밀번호를 바꾼다. 그런데 폼만큼 사람을 쉽게 지치게 하는 화면도 드물다. 적으려는 순간 안내 글이 사라지고, 다 적고 나서야 맨 위에 붉은 글이 뜨고, 하이픈을 안 넣었다고 번호를 거절당한다. 이 장은 폼을 사람과 화면이 주고받는 짧은 대화로 보고, 그 대화를 망치는 작은 결정들을 하나씩 고친다. 그리고 책방 E의 모임 신청 폼을 처음부터 다시 짠다.
- 라벨과 자리표시자의 차이를 알고, 자리표시자만 둔 칸이 기억·대비·검토에서 무엇을 잃는지 설명한다.
- 칸의 폭이 기대하는 답의 길이를 알려 준다는 것을 알고, 좁은 화면에서는 어디까지 따를지 정한다.
type·inputmode·autocomplete로 알맞은 키보드와 자동 완성을 불러 입력의 수고를 줄인다.- 형식은 사람이 아니라 기계가 맞추게 하고, 고칠 방법을 말하는 오류 문구를 쓴다.
- 오류를 알리는 시점(입력 중·칸을 떠날 때·제출 때)과 자리(위 요약·칸 아래)를 비교하고, 상황에 맞게 고른다.
- 필수 표시의 관례와 칸을 줄이는 원칙을 알고, 긴 폼을 단계로 나눌지 판단한다.
폼은 짧은 대화다
사람이 정보를 적어 보내는 화면을 폼(Form)이라고 한다. 웹 페이지 대부분은 읽히기만 하지만, 폼은 읽는 사람에게 일을 시킨다. 폼 안에서 한 가지 정보를 받는 상자를 입력 칸(Input field)이라고 하고, 칸이 무엇을 받는지 알려 주는 이름표를 라벨(Label)이라고 한다. 칸 안에 흐린 글씨로 미리 적혀 있다가 입력을 시작하면 사라지는 글은 자리표시자(Placeholder)다.
폼을 대화로 생각하면 좋은 폼의 조건이 쉽게 보인다. 좋은 상대는 무엇을 묻는지 분명히 말하고(라벨), 대답하는 동안 끼어들지 않고(검증 시점), 잘못 알아들었을 때는 바로 그 자리에서 어떻게 고치면 되는지 알려 준다(오류 위치와 문구). 그리고 필요 없는 것을 묻지 않는다(칸 줄이기). 아래 그림은 책방 E의 옛 웹사이트에 있던 모임 신청 폼을 다시 그린 것이다. 2019년쯤 산 템플릿에 딸려 온 폼이라 이 장에서 고칠 거의 모든 문제가 들어 있다.
그림 속 문제 가운데 어느 것도 "디자인이 촌스럽다" 같은 취향의 문제가 아니다. 모두 사람이 폼을 채우는 동안 머릿속에서 무엇을 기억해야 하는지, 눈이 어디로 가야 하는지, 손가락이 몇 번 움직여야 하는지의 문제다. 그래서 폼 디자인은 겉모습보다 순서와 시점을 설계하는 일에 가깝다. 폼 설계의 고전으로 꼽히는 책들, 예를 들어 캐럴라인 재럿과 제리 개프니의 『Forms that Work』(2008)와 루크 로블레프스키의 『Web Form Design: Filling in the Blanks』(2008)도 폼을 "질문과 대답의 대화"로 보는 데서 출발한다.
autocomplete), 3.3.1 오류 식별(어느 칸이 왜 틀렸는지 글로), 3.3.2 레이블 또는 지시(라벨과 안내), 3.3.3 오류 수정 제안(고칠 방법을 알려 준다), 3.3.7 중복 입력(2.2에 새로 생김, 같은 과정에서 이미 적은 것을 다시 적게 하지 않는다)이다. 이 장은 시각 디자인 쪽에서 이 기준들을 만나고, 화면 낭독기와 키보드로 쓰는 폼은 11장에서 다시 본다.
라벨과 자리표시자
칸 안에 흐린 글씨로 "이름"이라고 적어 두면 라벨이 따로 필요 없어 보인다. 화면도 깔끔해지고 세로 공간도 아낀다. 그래서 많은 템플릿이 자리표시자를 라벨 대신 쓴다. 문제는 자리표시자가 입력을 시작하는 순간 사라진다는 데 있다. 대화로 치면, 질문을 한 번 말한 뒤 대답을 시작하자마자 질문을 지워 버리는 상대다.
아래 목업에서 세 가지 방식을 바꿔 가며 직접 적어 본다. "인원" 칸에는 "본인 포함, 최대 4명"이라는 안내가 있다. 숫자를 적고 나서 그 안내가 어디에 남는지 본다. "예시 값 채우기"를 누르면 세 칸이 채워진 상태, 곧 제출 직전에 다시 훑어보는 순간이 된다.
라벨, 자리표시자, 떠오르는 라벨
모임 신청
ART.contrast로 계산한 값이다. 기본 자리표시자 색은 많은 브라우저가 쓰는 흐린 회색에 가깝게 잡았다.)자리표시자만 둔 칸은 세 번 실패한다. 첫째, 기억. 적는 동안 질문과 안내가 사라지므로 사람이 그것을 머리에 들고 있어야 한다. 짧은 이름 칸이면 괜찮지만 "본인 포함" 같은 조건이 붙으면 금세 잊는다. 둘째, 대비. 자리표시자는 "아직 안 적었다"는 것을 보여 주려고 일부러 흐리게 칠한다. 그래서 대부분 글자 대비 기준(WCAG 1.4.3, 4.5:1)에 못 미친다. 진하게 칠하면 이번에는 이미 채운 칸과 구별이 안 된다. 흐린 것이 자리표시자의 정체성이라 둘을 다 얻을 수 없다. 셋째, 검토. 다 채운 폼을 제출 전에 훑어볼 때 칸마다 값만 있고 이름이 없다. 화면 낭독기 사용자에게는 더 나쁘다. 자리표시자는 칸의 이름으로 읽히지 않을 수도 있고, 읽히더라도 값을 적은 뒤에는 사라진다.
칸 위 라벨은 좁은 휴대폰 화면에서 특히 유리하다. 라벨이 아무리 길어도 칸의 폭을 빼앗지 않고, 화면 글자를 크게 키운 사람에게도 라벨과 칸이 한 줄씩 내려온다. 칸 왼쪽 라벨은 넓은 화면에서 긴 폼의 세로 길이를 줄이고, 라벨을 훑으며 원하는 칸을 찾기 좋아 관리자 화면처럼 같은 폼을 매일 쓰는 사람에게 맞기도 하다. 라벨 위치에 관한 작은 시선 추적 연구들(예: 마테오 펜조, "Label Placement in Forms", UXmatters, 2006)은 칸 위 라벨이 가장 빨리 훑어진다고 보고했지만 참가자가 적은 연구라, "칸 위 라벨은 대부분의 상황에서 무난하다" 정도로 받아들이는 것이 좋다.
그림 2와 시뮬레이터의 세 번째 방식인 떠오르는 라벨(Floating label)은 둘의 타협이다. 처음에는 자리표시자처럼 칸 안에 있다가, 칸을 누르면 작게 줄어 칸 위쪽 가장자리로 올라간다. 이름은 남지만 글자가 작아지고, 안내 글을 둘 자리가 따로 없어 결국 안내가 자리표시자로 돌아가기 쉽다. 쓰더라도 안내 글은 칸 밖에 둔다.
<label for="count">인원</label>
<p id="count-hint">본인 포함, 최대 4명</p>
<input id="count" inputmode="numeric" aria-describedby="count-hint">
코드에서 라벨은 <label for>로 칸과 이어 준다. 그러면 라벨 글자를 눌러도 칸에 커서가 들어가 누를 자리가 넓어지고(7장의 터치 타깃), 화면 낭독기는 칸에 들어갈 때 라벨을 읽는다. 안내 글은 aria-describedby로 이어 칸의 설명으로 함께 읽히게 한다. 자리표시자는 예시가 정말 도움이 될 때(예: "예: 2028-03-04") 라벨과 별도로 덧붙이는 보조 수단으로만 쓴다.
칸의 폭은 답의 길이를 말한다
칸의 생김새도 질문의 일부다. 우편번호 칸이 이름 칸만큼 넓으면 사람들은 잠깐 망설인다. 길게 적어야 하나? 반대로 주소 칸이 짧으면 동 이름까지만 적고 멈춘다. 칸의 폭은 기대하는 답의 길이를 말없이 알려 주는 단서다. 여러 줄을 받는 칸(<textarea>)이면 높이도 같은 말을 한다. 세 줄 높이의 칸은 "몇 문장 정도"를, 한 줄짜리 칸은 "한 줄로"를 말한다.
아래 목업은 칸 다섯 개짜리 폼이다. 칸 폭을 정하는 세 가지 방식을 바꾸고, 목업의 폭을 360px 휴대폰에서 넓은 화면까지 늘여 본다. 각 칸에는 예시 값이 들어 있다.
칸 폭이 주는 단서
칸 폭을 답 길이에 맞추면 폼이 들쭉날쭉해 보인다는 걱정이 있다. 하지만 모든 칸이 같은 왼쪽 정렬선에서 시작하는 한 오른쪽 끝이 다른 것은 어수선해 보이지 않는다(CompositionBook 12장의 정렬). 다만 이 원칙은 넓은 화면에서 의미가 크다. 휴대폰처럼 폭이 360px 안팎인 화면에서는 대부분의 칸이 화면 폭에 가까워지고, 그래도 괜찮다. 우편번호, 인원, 카드 유효기간처럼 정말 짧은 칸만 좁게 두는 정도로 충분하다.
폭이 길이를 알려 주는 것처럼, 칸을 나누는 방식도 형식을 알려 준다. 전화번호를 세 칸(010 / 1234 / 5678)으로 나누면 형식은 분명해지지만, 붙여 넣기가 깨지고 칸 사이를 옮겨 다녀야 한다. 대부분의 경우 한 칸으로 받고 형식은 기계가 맞추는 편이 낫다. 다음 두 절이 그 이야기다.
알맞은 키보드, 자동 완성
휴대폰에서 폼을 채울 때 가장 많이 하는 일은 키보드를 바꾸는 일이다. 한글 자판에서 숫자를 적으려면 "123"을 누르고, 이메일의 @를 찾으려면 영문 자판으로 갔다가 기호 자판으로 간다. 웹 페이지는 칸마다 어떤 키보드를 띄울지 브라우저에 알려 줄 수 있다. 세 가지 속성이 그 일을 한다.
| 속성 | 하는 일 | 예 |
|---|---|---|
type | 칸이 받는 값의 종류. 키보드뿐 아니라 브라우저의 검사와 의미도 바뀐다. | email(@가 있는 자판), tel(전화 숫자판), url, search |
inputmode | 값의 종류는 그대로 두고 키보드만 고른다. | numeric(숫자판), decimal(소수점 포함), tel, email |
autocomplete | 칸의 목적을 알려 브라우저가 저장된 정보를 제안하게 한다. | name, tel, email, postal-code, one-time-code(문자로 받은 인증번호) |
인원이나 인증번호처럼 숫자로만 된 값이라도 type="number"는 조심해서 쓴다. 이 형식은 "수량"을 위한 것이라 앞자리 0을 지우거나, 마우스 휠에 값이 바뀌거나, 칸 옆에 작은 위아래 화살표를 붙이는 등 브라우저마다 다르게 군다. 우편번호, 인증번호, 카드 번호처럼 숫자로 된 글자는 type="text"에 inputmode="numeric"을 쓰는 편이 안전하다.
아래 휴대폰 목업에서 칸의 종류를 고르고, 속성을 "기본"과 "알맞게"로 바꿔 본다. 키보드가 바뀌는 모습과, 그 값을 적는 데 드는 탭 수의 어림값을 비교한다.
칸이 부르는 키보드
one-time-code 덕에 문자로 받은 번호가 제안된다. ④ "브라우저에 저장된 정보가 있다"를 끄면 제안이 사라진다. (키보드 모양과 제안 방식은 운영 체제와 키보드 앱마다 다르다. 이 목업은 대표적인 모양을 단순하게 그렸다. 탭 수는 자판 전환과 글자 하나를 각각 한 번으로 센 어림값이다. 한글은 자모 하나를 한 번으로 셌다.)자동 완성은 작은 기능 같지만 폼의 수고를 가장 크게 줄인다. 이름, 휴대폰 번호, 이메일, 주소는 대부분의 브라우저가 저장해 두었다가 제안할 수 있다. 그러려면 칸이 무엇을 받는지 표준 이름(autocomplete 값)으로 알려 줘야 한다. WCAG 2.2의 1.3.5 입력 목적 식별(AA)이 바로 이것을 요구한다. 기억이나 손 움직임에 어려움이 있는 사람에게 자동 완성은 편의가 아니라 폼을 끝낼 수 있느냐의 문제다. 반대로 autocomplete="off"를 습관처럼 붙이는 템플릿이 많은데, 정말 저장하면 안 되는 값이 아니라면 떼는 것이 좋다.
같은 이유로, 한 과정 안에서 이미 받은 정보를 다시 적게 하지 않는다. 배송지와 청구지가 같으면 "위와 같음"을 고르게 하고, 앞 단계에서 적은 이메일을 다음 단계에서 또 묻지 않는다. WCAG 2.2에 새로 들어온 3.3.7 중복 입력(A)이다. 인증 과정에서 기억력 퍼즐(예: 비밀번호를 붙여 넣지 못하게 막기)을 요구하지 않는 3.3.8 접근 가능한 인증(AA)도 같은 결의 기준이다.
maximum-scale=1, user-scalable=no)을 쓰는 것은 확대가 필요한 사람을 막는 일이라 피한다(2장).
형식은 기계가 맞춘다
그림 1의 옛 폼은 휴대폰 번호를 "010-0000-0000" 형식으로만 받았다. 하이픈을 빼고 적으면, 띄어 쓰면, 붙여 넣은 번호에 국가 번호가 붙어 있으면 모두 거절했다. 하지만 이 네 가지는 모두 같은 번호다. 사람에게 기계의 형식을 강요하는 대신, 기계가 사람의 여러 형식을 받아 한 형식으로 정리하면 된다. 숫자만 뽑아내고, +82로 시작하면 0으로 바꾸고, 자리 수를 확인한 뒤 저장할 때 하이픈을 넣는다. 인터넷 초기의 통신 규약 문서(RFC 761, 1980)에 실려 널리 알려진 "보낼 때는 엄격하게, 받을 때는 너그럽게"라는 원칙이 폼에서도 통한다.
아래에서 같은 번호를 여러 모양으로 넣어 본다. 첫 번째 단추 묶음으로 검사 방식을, 두 번째 묶음으로 오류 문구의 방식을 바꾼다.
엄격한 칸, 너그러운 칸
"형식이 올바르지 않습니다"는 오류 문구의 대표적인 실패다. 무엇이 틀렸는지도, 어떻게 고치는지도 말하지 않는다. 좋은 오류 문구는 세 가지를 한 문장에 담는다. 어느 칸인지(칸 바로 아래에 두면 저절로 해결된다), 무엇이 문제인지, 어떻게 고치는지. "휴대폰 번호가 한 자리 모자랍니다. 010으로 시작하는 11자리를 적어 주세요."처럼. WCAG 2.2의 3.3.1 오류 식별(A)은 앞의 둘을, 3.3.3 오류 수정 제안(AA)은 마지막 하나를 요구한다.
언제, 어디에 알릴까
값이 맞는지 확인하는 일을 검증(Validation)이라고 하고, 사람이 폼을 다 채워 보내기 전에 칸마다 그 자리에서 알려 주는 방식을 인라인 검증(Inline validation)이라고 한다. 인라인 검증에는 두 가지 결정이 따른다. 언제 알릴지(글자 하나를 칠 때마다, 칸을 떠날 때, 제출할 때)와 어디에 알릴지(폼 맨 위 요약, 칸 바로 아래, 둘 다)다.
아래는 책방 E의 새 모임 신청 폼 시안이다. 두 결정을 바꿔 가며 직접 채우고 틀려 본다. "번호를 한 자씩 적어 보기"를 누르면 휴대폰 번호 칸에 사람이 한 글자씩 치듯 숫자가 들어간다. 오른쪽 아래 숫자는 적는 도중에 뜬 오류와, 고쳤는데도 남아 있던 오류를 센다.
오류를 알리는 시점과 자리
세 가지 시점에는 각각 자리가 있다. 글자마다 검사하면 반응은 빠르지만, 아직 다 적지 않은 값을 틀렸다고 말하게 된다. 열한 자리 번호의 첫 자리를 적는 순간 "번호가 짧다"고 하는 것은 정확하지만 쓸모없다. 다만 비밀번호 조건(여덟 자 이상, 숫자 포함)처럼 적는 동안 하나씩 채워지는 조건을 보여 줄 때는 글자마다가 맞다. 이때는 "오류"가 아니라 "진행"으로 보여 준다. 제출할 때만 검사하면 끼어들지는 않지만, 다 적은 뒤에야 한꺼번에 틀린 것을 알게 되고 고친 뒤에도 오류가 남는다. 칸을 떠날 때 검사하고, 이미 오류가 보이는 칸은 고치는 즉시 지우는 방식이 그 사이의 균형이다. "늦게 꾸짖고 빨리 칭찬한다"고 줄여 부르기도 한다. 어떤 방식이든 제출할 때 모든 칸을 한 번 더 검사하는 것은 기본이다.
인라인 검증이 오류와 작성 시간을 줄인다는 보고는 여럿 있다(예: 루크 로블레프스키, "Inline Validation in Web Forms", A List Apart, 2009에 소개된 사용성 시험). 다만 적은 수의 참가자로 한 시험이고 폼과 과제에 따라 결과가 달라질 수 있어, 숫자보다 방향을 참고하는 것이 좋다.
자리는 폼의 길이에 따라 다르게 고른다. 칸이 네댓 개인 짧은 폼은 칸 바로 아래 오류만으로 충분하다. 오류가 칸 옆에 있으니 "어느 칸"인지 따로 말할 필요가 없고, 눈이 이동할 거리도 짧다. 하지만 휴대폰에서 스크롤해야 하는 긴 폼이라면, 맨 아래 "신청하기"를 눌렀을 때 화면 밖 위쪽 칸에 생긴 오류가 보이지 않는다. 아래 시뮬레이터는 휴대폰 화면 하나 높이로 긴 폼을 보는 장면이다. 화면을 위아래로 끌어 스크롤한다.
화면 밖의 오류
긴 폼에서 제출이 실패하면 위 요약과 칸 아래 문구를 함께 쓰고, 화면(그리고 키보드 포커스)을 요약으로 옮기는 방식이 널리 쓰인다. 영국 정부 웹사이트의 공개 디자인 체계(GOV.UK Design System)가 이 방식을 "오류 요약" 부품으로 정리해 두었다. 요약에는 오류의 수와 각 오류로 가는 링크를 두고, 같은 문구를 해당 칸 아래에도 둔다. 요약은 "몇 개, 어디"를 한 번에 알려 주고, 칸 아래 문구는 고치는 동안 눈앞에 남는다. 짧은 폼에서는 요약 없이 칸 아래 문구만 두고, 제출에 실패하면 첫 번째 오류 칸으로 포커스를 옮긴다.
aria-describedby로 칸에 이어 칸에 들어갈 때 함께 읽히게 하고, 칸에는 aria-invalid="true"를 단다. 제출에 실패했을 때의 요약은 포커스를 요약으로 옮기거나 알림 역할(role="alert")로 읽히게 한다. WCAG 2.2의 4.1.3 상태 메시지(AA)는 포커스를 옮기지 않고 생기는 이런 알림도 보조 기술이 알 수 있어야 한다고 요구한다. 자세한 점검은 11장에서 한다.
필수 표시와 칸 줄이기
꼭 채워야 하는 칸을 알리는 관례는 라벨 옆 별표(Asterisk, *)다. 널리 쓰여 많은 사람이 알아보지만, 별표의 뜻은 어디엔가 따로 적어 두어야 하고(그림 1처럼 맨 아래에 숨으면 소용없다), 작고 붉은 별표는 놓치기 쉽다. 그래서 요즘은 다음 두 가지 중 하나를 고르는 경우가 많다.
- 대부분이 필수라면, 필수 칸에는 아무것도 붙이지 않고 몇 안 되는 선택 칸에 "(선택)"을 붙인다. 폼 위에 "모든 칸을 적어 주세요" 한 줄을 둔다.
- 필수와 선택이 섞여 있다면, 필수 칸에 별표나 "(필수)"를 붙이고 폼 위에서 그 뜻을 한 번 밝힌다. 별표를 쓰더라도 화면 낭독기에는 칸이 필수라는 것이 따로 전해지게(
required속성) 한다.
더 좋은 방법은 선택 칸을 없애는 것이다. 칸 하나하나는 사람의 시간과 주의를 쓴다. 칸이 왜 필요한지 설명할 수 없다면 지운다. 옛 폼의 생년월일과 주소가 그렇다. 모임 신청에 생일이나 집 주소는 필요 없다. 필요 없는 개인 정보를 모으지 않는 것은 친절이기 전에 법의 원칙이기도 하다. 개인정보 보호법(제16조)은 목적에 필요한 최소한의 개인 정보만 모으도록 정하고 있다. 모으지 않은 정보는 새어 나갈 일도 없다.
| 옛 폼의 칸 | 모임 신청에 필요한가 | 판단 |
|---|---|---|
| 이름 | 명단과 호명에 필요 | 둔다 |
| 휴대폰 번호 | 확인 문자와 일정 변경 연락 | 둔다 |
| 참가 모임 | 무엇을 신청하는지 | 둔다(목록 대신 고르기 단추) |
| 인원 | 자리 준비 | 둔다 |
| 이메일 | 연락은 문자로 충분 | 지운다 |
| 생년월일 | 쓸 데가 없다 | 지운다 |
| 주소 | 쓸 데가 없다 | 지운다 |
칸을 지우는 것만큼 칸의 종류를 바꾸는 것도 효과가 크다. 옛 폼의 "참가 모임"은 접힌 목록(<select>)이었다. 고를 것이 두세 개뿐이라면 펼쳐 둔 고르기 단추(라디오 단추)가 낫다. 한 번에 모든 선택지가 보이고, 한 번 눌러 끝난다. 반대로 선택지가 수십 개(예: 나라 목록)라면 접힌 목록이나 검색이 낫다.
단계 나누기
칸이 많은 폼을 여러 화면으로 나누는 것을 단계형 폼(Multi-step form, 마법사)이라고 한다. 첫 화면에 칸이 서너 개만 보여 덜 부담스럽고, 단계마다 한 가지 주제(누구인지, 무엇을 신청하는지, 어떻게 연락할지)에 집중할 수 있다. 대신 화면을 넘길 때마다 기다림과 누름이 하나씩 늘고, 앞 단계로 돌아가 고치기가 번거로워지며, 전체 길이가 숨겨진다.
나눌지 말지에 대한 연구 결과는 상황마다 다르다. 그래서 아래 시뮬레이터는 실제 자료가 아니라, 판단의 구조를 보여 주려고 이 장이 정한 가상 모형이다. 칸 하나마다 일정 비율이 포기하고, 첫 화면에 칸이 많으면 시작하기 전에 떠나는 사람이 생기고, 화면을 넘길 때마다 조금 더 떠난다고 가정했다.
단계를 나누면 끝까지 가는가(가상 모형)
모형의 숫자는 지어낸 것이지만 구조는 쓸모 있다. 첫째, 칸을 줄이는 것이 단계를 나누는 것보다 먼저다. 둘째, 단계를 나누는 이득은 칸이 많고 주제가 분명히 갈릴 때 생긴다. 셋째, 나누었다면 사람이 어디쯤 와 있는지 알려 준다. "2/3 단계"와 단계 이름을 보여 주고, 앞 단계로 돌아가도 적은 값이 사라지지 않게 한다. 마지막 단계에서는 적은 내용을 한 화면에 모아 보여 주고 고칠 수 있게 한다. 되돌릴 수 없는 결정(결제, 법적 약속)이 걸린 폼이라면 이 확인 화면이 WCAG 2.2의 3.3.4 오류 예방(AA)이 요구하는 장치이기도 하다.
단계로 나누든 한 화면에 두든 칸의 순서도 대화처럼 짠다. 쉬운 것과 무엇을 하려는지(참가할 모임)를 먼저, 개인 정보(이름, 연락처)를 그다음에 둔다. 사람들은 무엇을 얻는지 알고 나서 자기 정보를 내놓는다.
서윤의 웹 개편 노트
일곱 칸에서 네 칸으로
2월 둘째 주, 서윤은 모임 신청 폼에 매달렸다. 주인은 "모임 신청을 전화로 받느라 하루가 다 가요"라고 했다. 옛 사이트에도 신청 폼은 있었다. 그런데 왜 다들 전화를 할까. 서윤은 도경에게 옛 폼으로 2월 낭독 모임을 신청해 달라고 부탁하고 옆에서 지켜보았다.
도경의 휴대폰은 글자 크기가 가장 크게 설정되어 있어서, 자리표시자 "인원(본인 포함, 최대 4명)"이 "인원(본인 포…"에서 잘려 있었다. 도경은 친구 둘과 함께 갈 생각이라 "2"를 적었다가, 칸이 비면서 무엇을 적는 칸이었는지 잠깐 헷갈렸다. 휴대폰 번호는 늘 하던 대로 숫자만 적었다. 생년월일 칸에서는 "이걸 왜 물어?"라며 한참 멈췄다. "보내기"를 누르자 맨 위에 "입력 정보를 다시 확인하십시오"가 떴는데, 화면은 맨 아래에 있어서 도경은 아무 일도 일어나지 않은 줄 알았다. 두 번 더 누른 뒤 도경은 휴대폰을 내려놓고 말했다. "그냥 전화할게."
지후가 옛 폼의 코드를 열어 보니 문제가 더 보였다. 라벨 요소가 하나도 없었고, 모든 칸에 autocomplete="off"가 붙어 있었고, 번호는 하이픈이 있는 형식만 통과시켰다. "번호 형식은 제가 정리할게요. 사람이 하이픈을 맞출 이유가 없어요." 서윤은 이 장의 시뮬레이터로 세 가지를 비교한 뒤 다음처럼 정했다.
| 항목 | 옛 폼 | 서윤의 선택 |
|---|---|---|
| 칸 | 7개(이름, 이메일, 휴대폰 번호, 생년월일, 주소, 참가 모임, 인원) | 4개: 참가 모임 → 이름 → 휴대폰 번호 → 인원 |
| 라벨 | 자리표시자만 | 칸 위 라벨(14px, 굵게), 안내 글은 라벨 아래 13px, 자리표시자는 쓰지 않음 |
| 간격·크기 | 제각각 | 라벨–칸 8px, 칸 높이 48px(7장의 터치 타깃 44px 이상), 칸 사이 24px, 입력 글자 17px |
| 참가 모임 | 접힌 목록 | 펼친 고르기 단추 2개(한 줄 높이 44px 이상) |
| 휴대폰 번호 | 010-0000-0000만 | type="tel", autocomplete="tel", 어떤 모양이든 숫자만 뽑아 010-0000-0000으로 저장 |
| 인원 | 칸 하나, 안내는 자리표시자 | inputmode="numeric", 칸 폭 110px, 라벨 아래 "본인 포함, 1~4명" |
| 검증 시점 | 제출할 때만 | 칸을 떠날 때. 오류가 보이는 칸은 고치는 즉시 지움. 제출 때 전체 재검사 후 첫 오류 칸으로 포커스 |
| 오류 자리와 모양 | 맨 위 한 줄 | 칸 바로 아래(4px), 위험 색 #c53732(흰 바탕 대비 5.29) + 느낌표 아이콘 + 고칠 방법을 말하는 문구, 칸 테두리 2px |
| 필수 표시 | 맨 아래 별표 설명 | 네 칸 모두 필수라 별표 없이 폼 위에 "네 칸 모두 적어 주세요" 한 줄 |
| 단계 | 한 화면 | 한 화면 유지(칸 4개라 나누지 않음) |
서윤은 처음에 오류 요약도 위에 두려 했다. 지후가 "네 칸짜리 폼이면 휴대폰에서도 한 화면에 거의 다 들어와요. 요약은 긴 폼에서 쓰고, 여기선 첫 오류 칸으로 포커스만 옮기죠"라고 해서 칸 아래 문구만 남겼다. 이메일 칸을 지울 때는 주인이 망설였다. 소식지를 보내고 싶다는 것이었다. 서윤은 신청 폼과 소식지 구독을 나누자고 했다. 소식지는 신청이 끝난 화면에서 "소식지도 받으시겠어요?"라고 따로 묻기로 했다. 신청하러 온 사람에게 신청에 필요한 것만 묻는다는 원칙이다.
새 시안으로 도경이 다시 신청했다. 고르기 단추 하나를 누르고, 이름은 휴대폰이 제안한 것을 한 번 눌러 넣었다. 번호에서 일부러 한 자리를 빼 보라고 하자, 다음 칸으로 넘어가는 순간 칸 바로 아래에 "번호가 한 자리 모자랍니다"가 떴고, 한 자리를 더하자 바로 사라졌다. 도경은 "이건 전화보다 빠르네"라고 했다.
#c53732·아이콘·문구로, 칸 수 7 → 4(참가 모임, 이름, 휴대폰 번호, 인원). 번호는 어떤 모양이든 받아 정리해 저장한다. 칸 높이 48px, 칸 사이 24px, 입력 글자 17px. 단계는 나누지 않는다.핵심 정리
- 폼은 사람과 화면의 짧은 대화다. 무엇을 묻는지 분명히 말하고, 대답하는 동안 끼어들지 않고, 틀리면 그 자리에서 고칠 방법을 알려 주고, 필요 없는 것을 묻지 않는다.
- 자리표시자는 라벨이 아니다. 적는 순간 사라져 기억에 기대게 하고, 흐린 색이라 대비가 낮으며, 다 채운 뒤에는 칸의 이름을 잃는다. 라벨은 칸 위에, 안내 글은 라벨 아래에 둔다.
- 칸의 폭과 높이는 기대하는 답의 길이를 알려 준다. 넓은 화면에서는 짧은 칸을 짧게 두고, 좁은 화면에서는 대부분 화면 폭에 맞춘다.
type·inputmode는 알맞은 키보드를,autocomplete는 저장된 정보의 제안을 부른다(WCAG 1.3.5). 숫자로 된 글자에는type="number"대신inputmode="numeric"을 쓴다. 입력 글자는 16px 이상.- 형식은 기계가 맞춘다. 여러 모양의 입력을 받아 한 형식으로 정리하고, 오류 문구는 어느 칸·무엇이 문제·어떻게 고치는지를 말한다(WCAG 3.3.1, 3.3.3). 색만으로 알리지 않는다.
- 칸을 떠날 때 검증하고 고치는 즉시 오류를 지우는 방식이 균형점이다. 짧은 폼은 칸 아래 문구만, 스크롤이 필요한 긴 폼은 위 요약과 칸 아래 문구를 함께 쓰고 요약으로 이동한다.
- 필수 칸이 대부분이면 선택 칸에만 "(선택)"을 붙인다. 더 좋은 것은 필요 없는 칸을 지우는 것이다. 단계 나누기는 칸을 줄인 다음, 칸이 많고 주제가 갈릴 때 진행 표시와 함께 쓴다.
확인 퀴즈
1. 라벨 없이 칸 안의 자리표시자에 "인원(본인 포함, 최대 4명)"이라고만 적어 둔 폼의 문제로 가장 알맞은 것은?
2. 휴대폰에서 6자리 인증번호를 받는 칸을 만든다. 가장 알맞은 설정은?
type="number"(앞자리 0 삭제, 휠로 값 변경 등)보다 inputmode="numeric"이 안전하다. one-time-code는 문자로 받은 번호를 제안하게 해 입력을 한 번으로 줄인다. autocomplete="off"는 이 도움을 막고, 이메일 형식은 엉뚱한 키보드를 부른다.3. 사람이 휴대폰 번호 칸에 첫 숫자 "0"을 적자마자 "번호가 너무 짧습니다"라는 오류가 떴다. 어떤 검증 방식 때문이고, 무엇으로 바꾸는 것이 좋은가?
4. 칸이 열두 개인 긴 폼을 휴대폰에서 끝까지 내려와 "제출"을 눌렀는데, 오류가 맨 위쪽 칸 두 개에 있다. 가장 알맞은 처리는?