더 나은 폼을 만드는 몇 가지 팁


폼 사용성은 웹 개발에서 매우 중요합니다. 웹에서는 드문 상호작용 경험이기 때문입니다.

사용자들은 웹에서 주로 “보기” 활동을 합니다. “쓰기”는 상대적으로 적습니다. 이 때 사용성이 나쁘면 강렬한 인상을 받습니다.

즉, 사이트 인상을 좌우하므로 기획/구현시 주의를 기울여야 합니다.

브라우저 기능 준수

기본은 브라우저의 기능을 준수하는 것입니다.

대표적 사례는 input에서 엔터를 쳤을 때 폼이 제출되는 것이죠. 우리는 생각보다 input에서 엔터를 많이 칩니다. 검색할 때를 생각해 보세요.

탭키, 방향키도 잘 작동해야 합니다.

취소 버튼 금지

제출 버튼 옆에 있는 취소 버튼은 실수를 유도하는 함정이나 다름없습니다. 실수로 취소를 눌러 폼 내용을 모두 날린 사용자들은 허탈해집니다. 폼을 다시 작성할 의욕을 잃어버릴 수도 있습니다.

취소 버튼이 없어도 사용자들은 뒤로 가기를 눌러 폼 제출을 얼마든지 취소할 수 있습니다.

미숙련자들(예컨대 연세 있으신 분들)에게는 취소 버튼이 유용할 것이라고 생각할 수도 있습니다. 그러나 미숙련자일수록 웹브라우저의 뒤로 가기 버튼을 더욱 많이 사용합니다. 따라서 걱정말고 취소 버튼을 없애면 됩니다.

스마트폰 가상 키보드 지원

스마트폰으로 폼 입력을 할 때 inputmode 속성을 이용해 필드 유형에 맞는 적절한 가상 키보드를 제공해야 합니다. 사용성에서 중요한 지점입니다.

이게 되지 않으면 전문성이 떨어지는 사이트로 보이게 됩니다.

<!-- 가상 키보드 제어 -->
<input type="text" inputmode="email">
<input type="text" inputmode="numeric">
<input type="text" inputmode="tel">
<input type="text" inputmode="url">
<input type="text" inputmode="decimal">
<input type="text" inputmode="search">

input type과 inputmode

스마트폰 가상키보드 지원을 할 때 typeinputmode를 활용할 수 있습니다. 그런데 이 둘은 서로 목적이 다릅니다.

type은 데이터의 유형을 좌우합니다. 가상 키보드 제공뿐 아니라 밸리데이션까지 한다는 점이 inputmode와 차이입니다.

반면 inputmode는 가상 키보드만 제어하는 속성입니다.

따라서 밸리데이션을 JS로 처리한다면 type보다는 inputmode를 활용하는 것이 더 나은 선택일 수 있습니다.

밸리데이션

밸리데이션은 꼭 필요합니다.

그런데 밸리데이션의 기술적 방법보다 중요한 것이 있습니다. 사용자가 에러를 명료하게 알 수 있어야 한다는 점입니다.

에러가 난 지점으로 focus를 해 주면 더 좋습니다. 그러나 에러 메시지가 명확해서 사용자들이 무리없이 에러 메시지를 읽고 눈치챌 수 있다면 focus가 없어도 사용자들이 아주 불편하지는 않을 겁니다.

에러 표시 없이 폼이 제출되지 않는 경우를 드물게 만나는데 그러면 사용자는 답답해 미칩니다.

에러 메시지가 모호한 것도 사용자를 답답하게 하기는 마찬가지입니다.

HTML 내이티브 밸리데이션

HTML 내이티브 밸리데이션은 기본 명시성은 다소 떨어집니다.

내이티브 밸리데이션을 할 때 뜨는 팝업 에러 메시지에 명료한 메시지를 표시하려면 title 속성에 메시지를 넣습니다.

title 속성을 이용하면 html native 밸리데이션에서도 커스텀 에러 메시지를 표현할 수 있습니다. 그러나 밋밋한 레이어 팝업 형태의 메시지는 미숙련자들이 알아보기 힘들 수도 있습니다.

HTML 내이티브 밸리데이션만 쓸 때 매우 주의를 기울여야 하는 사항이 있습니다.

에러가 났는데 팝업 안내 메시지가 제대로 보이지 않는 경우입니다. 문제를 알 수 없는데 제출이 되지 않는 이 상황은 미숙련자에 치명적입니다.

따라서 여러 상황에서 테스트를 해 봐야 합니다.

내이티브 밸리데이션은 :user-invalid 가상 선택자와 CSS를 합쳐 스타일링을 하고 에러 메시지를 명확하게 표시할 수 있습니다. 이걸 잘 활용하는 편이 팝업 에러 메시지만 사용하는 것보다 훨씬 나을 겁니다.

좀더 생각할 이슈들

type number와 inputmode numeric

input type number 지정시 고려할 점이 있습니다. 수량·서수인가 그저 값이 숫자일 뿐인가 하는 점입니다.

개수나 금액처럼 수량이거나 순서, 날짜처럼 서수면 type="number"가 좋습니다 (물론 날짜를 date 타입이나 달력 JS로 구현하지 않은 경우겠죠). 방향키 조정이 되니까요. 전화번호나 주민등록번호 같은 고유번호라면 inputmode="numeric"만 쓰는 게 나을 수 있습니다.

숫자 입력시 선택 블록 씌우기

기본값이 있는 숫자를 입력할 때는 onfocus="this.select()" 같은 코드로 기본 선택을 해 주면 좋습니다. 구입 수량 같은 것을 선택할 때 인풋에 기본값 1이 들어있죠. 이걸 스마트폰에서 수정하려면 우선 1을 지우고 시작해야 하는데요. 기본으로 선택을 해 주면 지우지 않고 값을 바로 덮어쓸 수 있습니다.

<label for="count">구입 수량</label>
<input value="1"
onfocus="this.select()"
type="number" inputmode="numeric"
id="count">개

JS 라이브러리 사용시 에러 알림 시점

JS 밸리데이션 패키지를 사용하면 폼 제출 전에 에러를 알릴 수 있습니다. 하지만 입력을 다 마치기도 전에 에러를 표시하면 사용자는 불안합니다. 이메일을 입력하는 중인데 형식에 맞지 않다고 에러가 뜨는 식이죠.

JS 패키지 대부분은 아마 에러를 알려주는 시점을 설정할 수 있을 겁니다.

저는 에러 표시는 blur나 change 이벤트가 발생했을 때, 에러 해결 여부는 실시간으로 알려 주는 게 좋다고 봅니다.

제가 좋아하는 VeeValidate는 4가지 모드를 제공합니다.

JS 밸리데이션 라이브러리 vs 직접 구현

JS 밸리데이션 라이브러리를 선택하는 것은 복잡한 밸리데이션 UI를 손쉽게 구현할 수 있게 해 줄 수도 있습니다.

그런데 거꾸로, 커스텀한 조건을 구현하는 게 너무 까다로운 경우도 있습니다. 그러면 직접 구현하는 것보다 일이 훨씬 복잡해집니다.

그래서 라이브러리를 고를 땐 커스텀 구현이 얼마나 쉽고 유연한지 꼭 따져 봐야 합니다.

밸리데이션 로직이 복잡한 페이지라면 if문을 나열하는 게 개발자에게 가장 쉽고 사용자들에게도 명확한 밸리데이션이 될 수도 있습니다.

사용자 제어권 문제

alert으로 하는 에러 안내는?

밸리데이션을 할 때 alert으로 안내하는 것은 어떨까요? 우선 개발자 입장에서는 가장 간편한 방법입니다.

사용자 입장에서는 의외로 이게 명시적이어서 그리 나쁘진 않습니다(물론 읽지도 않고 끄는 경우가 생길 수 있습니다).

약간 없어 보인다는 점도 단점입니다만 아주 크지는 않다고 생각합니다.

유의점은 alert이 focus를 뺏는다는 점입니다. 그 자체로는 문제가 아니지만 만약 사용자 제어권을 빼앗는 형태로 focus를 뺏는다면 문제입니다.

예컨대 blur 이벤트에 검증을 걸어서 틀린 값이면 alert()을 하고 다시 해당 입력칸으로 focus()를 하는 경우가 있습니다. 나쁘죠. 커서가 빠져나올 수 없는 감옥에 갇히게 되고 사용자는 답답해할 수 있습니다.

숫자 input에 쉼표를 찍어 줘야 할까?

입력시 숫자에 쉼표를 찍어 줘야 할까요? 네다섯 자리 정도라면 찍을 필요가 없다고 생각합니다. 그러나 큰 수를 다룬다면 쉼표가 있는 편이 좋을 것입니다.

input에 직접 쉼표를 찍어준다면 주의할 점이 있습니다. input value에 쉼표를 찍은 뒤 value를 replace하게 될 텐데요. 그 때 커서가 맨 뒤로 이동한다는 점입니다. 예컨대 숫자 맨 앞자리를 수정하려고 지우는 순간 커서가 맨 뒤로 이동해 버리는 일이 벌어집니다.

사용성이 부족한 사례. 한글을 입력하면 NaN이 뜨고 백스페이스를 눌러도 NaN은 지워지지 않습니다. 숫자를 입력해야 그제야 괜찮아집니다. 숫자 맨 앞자리를 수정하려고 지우는 순간 앞의 0들이 모두 지워져 처음부터 다시 입력해야 합니다.

이런 동작은 사용자의 입력 제어권에 민감한 사람들에게는 꽤 불편한 느낌을 줍니다.

그래서 input에 직접 쉼표를 찍으려면 커서의 위치까지 파악해 커서 위치까지 제자리로 돌려 두는 코딩을 해야 합니다.

아주 깔끔한 사용자 경험을 줄 게 아니라면 차라리 입력 칸과 보기 칸을 나누는 게 낫습니다. 입력 칸은 건드리지 않고, 보기 칸에서는 쉼표 숫자와 한국어로 읽은 것을 동시에 보여 주는 것이죠. 아래 예제를 보세요.

아이폰 기업은행 앱은 아예 input에 커서를 표시하지 않게 해 이런 문제를 해결했습니다.

전화번호에서 -를 자동으로 입력해 줘야 할까?

전화번호를 입력할 때 숫자 사이에 -를 자동으로 입력해 주는 것도 마찬가지입니다. 사용자가 예상하지 못하게 동작한다면 좋은 선택이 아닙니다.

예컨대 -가 추가되면서 백스페이스가 작동하지 않는 경우를 경험한 적이 있는데요, 그렇게 할 바에는 기능이 없는 게 더 낫습니다.

입력을 마친 뒤 오타를 발견하고 수정하려고 방향키를 누르는데 작동하지 않는다면 그것도 문제입니다.

입력칸을 세 칸으로 만드는 것은 좋지 않습니다(특수한 사정이 있는 게 아니라면). 미숙련자는 전화번호 하나 입력하려고 마우스를 세 번이나 클릭해야 합니다.

차라리 입력은 사용자가 자유롭게 하도록 하고 백단에서 -를 넣는 선택을 하는 것이 속편합니다.

사용성과 제어권은 같이 갑니다

폼 사용성에서 사용자 제어권은 핵심적입니다. 기획자 입장에서 사용자가 편리하라고 넣은 기능일지라도 사용자가 폼을 제어하는 능력을 빼앗는다면 사용성이 떨어지게 됩니다.

앞서 검토한 사례들을 정리해 보면 이렇습니다.

  • 밸리데이션으로 폼 제출을 막으면서 명확한 에러 메시지를 보여 주지 않는다면 사용자는 할 수 있는 게 없다고 느끼므로 사용자 제어권을 빼앗는 것입니다.
  • input에 오류가 있을 때 blur 이벤트에서 alert을 띄운 뒤 다시 원래 자리로 foucs해 주는 것은 사용자가 폼을 자유롭게 이동하지 못하게 함으로써 사용자의 제어권을 빼앗는 일이 됩니다.
  • 숫자 입력시 쉼표를 찍다가 커서 위치를 맨 뒤로 옮기는 것은 사용자의 커서 제어권을 빼앗는 것입니다.
  • 전화번호 입력시 자동으로 -를 입력해 주다가 몇몇 입력 기능을 막게 되는 것은 사용자 제어권을 빼앗는 것입니다.

결론

폼 사용성을 위해 신경쓸 일들은 자잘한 것들이 많습니다. 어려운 것은 거의 없습니다. 그런데 이런 디테일이 바로 결과물의 완성도를 좌우합니다.

폼은 상호작용하는 요소입니다. “보기”보다 사용자의 능동성이 더 발휘되는 기능입니다. 웹사이트를 운영하는 입장에서 능동적인 사용자는 반갑습니다. 이런 폼이 더 편리해지면 능동적인 상호작용이 사소한 이유로 줄어드는 것을 막을 수 있습니다.

👇 카테고리 글 목록

, , , ,

대표글

댓글 남기기