03.1 검증을 브라우저가 알아서 해준다고요?

많은 분들이 폼 검증이라고 하면 곧장 자바스크립트부터 떠올려요. if문으로 값이 비었는지, 형식이 맞는지 일일이 짜는 거죠. 그런데 실무에선 그 전에 챙기는 게 있어요. 브라우저 기본 검증(built-in validation, 내장 검증)이에요.


HTML 속성 몇 개만 붙이면, 자바스크립트 한 줄 없이도 브라우저가 제출 전에 값을 검사해줘요. 형식이 틀리면 제출을 막고 안내 말풍선을 띄워주죠. 이걸 잘 쓰면 검증 코드의 상당 부분을 아낄 수 있어요. 오늘은 이 속성들을 하나씩 손에 익혀볼게요.

03.2 required는 어떻게 써요?

제일 많이 쓰는 속성은 단연 required(필수)예요. 이 속성이 붙은 칸은 비어 있으면 제출이 안 돼요.


상황: 이름은 반드시 받아야 해요.
<form>
<label for="name">이름</label>
<input id="name" type="text" required>
<button>가입</button>
</form>


결과는 이래요. 사용자가 이름 칸을 비운 채 가입 버튼을 누르면, 서버로 보내지지 않고 그 칸에 "이 입력란을 작성하세요" 같은 말풍선이 떠요. 커서도 자동으로 그 칸으로 옮겨가죠. 우리가 짠 코드는 하나도 없는데 브라우저가 알아서 이만큼 해줘요.


라디오 버튼이나 체크박스에도 required를 쓸 수 있어요. 약관 동의 체크박스에 붙이면, 체크하지 않고는 제출을 못 하게 막을 수 있어요.


상황: 약관에 동의해야만 가입돼요.
<input type="checkbox" required> 이용약관에 동의합니다


이러면 사용자가 체크박스를 안 누르고 가입을 시도할 때 "동의해달라"는 안내가 뜨며 막혀요. 실무에서 정말 자주 쓰는 패턴이라 꼭 손에 익혀두면 좋아요.

03.3 길이랑 형식은 어떻게 제한해요?

길이를 제한할 땐 minlength(최소 글자 수)와 maxlength(최대 글자 수)를 써요. 비밀번호를 8자 이상 받고 싶을 때 딱이죠.


<input type="password" minlength="8" maxlength="20" required>


이러면 사용자가 8자보다 짧게 넣고 제출할 때 더 길게 쓰라는 안내가 뜨면서 막혀요. maxlength는 조금 달라요. 아예 그 이상은 타이핑 자체가 안 돼요.


형식을 더 정교하게 잡고 싶으면 pattern(패턴)을 써요. pattern에는 정규식(regular expression, 규칙 문자열)을 넣어요. 예를 들어 "숫자 4자리"만 받고 싶다면 이렇게요.


상황: 인증번호 4자리를 받아요.
<input type="text" pattern="[0-9]{4}" title="숫자 4자리를 입력하세요">


여기서 [0-9]{4}는 "0부터 9까지의 숫자가 딱 4개"라는 뜻이에요. 사용자가 "12ab"나 "123"을 넣으면 형식이 안 맞다며 제출이 막혀요. title에 적은 안내문은 말풍선에 함께 보여줘서 뭘 넣어야 하는지 알려줘요. pattern은 이메일, 전화번호, 우편번호처럼 정해진 형식을 받을 때 아주 강력해요.

03.4 숫자 범위는 어떻게 막아요?

앞에서 type=number를 볼 때 잠깐 나왔던 min, max, step도 사실 브라우저 기본 검증의 일부예요. 숫자나 날짜의 범위를 지켜주죠.


상황: 할인율을 0부터 100까지, 5단위로만 받아요.
<input type="number" min="0" max="100" step="5">


결과를 볼게요. 사용자가 -10이나 200을 넣으면 범위를 벗어났다며 막혀요. step="5"를 줬으니 3이나 7처럼 5의 배수가 아닌 값도 어긋난 값이라며 안내가 떠요. 날짜 칸(type=date)에 min과 max를 주면 "오늘 이후 날짜만" 같은 제한도 만들 수 있고요.

03.5 검증이 실패하면 정확히 무슨 일이 생겨요?

이 흐름을 한 번 제대로 정리해두면 좋아요. 사용자가 제출 버튼을 누르면 브라우저는 순서대로 이렇게 움직여요.


먼저 폼 안의 모든 칸을 위에서부터 검사해요. 그러다 규칙을 어긴 첫 번째 칸을 만나면 거기서 멈춰요. 그 칸으로 포커스를 옮기고, 옆에 안내 말풍선을 띄우고, 제출을 취소해요. 그래서 서버로는 아무것도 안 가요.


중요한 건 한 번에 하나씩 알려준다는 거예요. 첫 칸을 고치고 다시 제출하면, 그다음 문제 있는 칸을 짚어줘요. 그래서 사용자는 위에서 아래로 차례차례 고쳐나가게 돼요. 이 기본 동작을 알아두면, 나중에 직접 검증을 짤 때도 같은 흐름을 흉내 내면 되니 편해요.


여기서 실무 팁 하나. 이 기본 말풍선은 사용자가 제출을 시도할 때 뜨는 게 기본이에요. 그래서 사용자는 칸을 채우는 동안엔 방해받지 않다가, 제출 순간에 딱 안내를 받죠. 이 타이밍이 꽤 자연스러워서, 간단한 폼이라면 브라우저 기본 검증만으로도 충분히 쓸 만한 UX가 나와요. 굳이 자바스크립트로 다 짜지 않아도 되는 경우가 생각보다 많다는 거예요.

03.6 기본 검증을 끄고 싶으면 어떻게 해요?

브라우저 기본 말풍선은 편하지만, 디자인을 바꿀 수가 없어요. 회색 말풍선이 브라우저마다 모양도 다르고요. 그래서 실무에서는 기본 검증 UI를 끄고 직접 에러를 그리는 경우가 많아요. 이때 쓰는 게 novalidate예요.


상황: 검증은 내가 직접 그릴 거예요.
<form novalidate>
<input type="email" required>
<button>제출</button>
</form>


form에 novalidate를 붙이면 브라우저의 기본 말풍선과 자동 차단이 꺼져요. 재밌는 건, 검증 규칙 자체(required, pattern 같은 것)는 그대로 살아 있다는 거예요. 브라우저가 대신 막아주지만 않을 뿐이죠. 그래서 자바스크립트로 그 규칙들을 읽어서 내 스타일의 에러 메시지를 직접 띄울 수 있어요.


특정 버튼만 검증을 건너뛰게 하고 싶으면 버튼에 formnovalidate를 줘요. "임시 저장" 버튼처럼 필수 칸을 안 채워도 눌러야 하는 경우에 딱이에요. 한 폼 안에 "제출"과 "임시 저장" 버튼이 나란히 있을 때, 제출은 전체 검증을 돌리고 임시 저장만 건너뛰게 만들 수 있는 거죠.

03.7 오늘 배운 걸 정리해볼게요

브라우저 기본 검증은 코드 없이 폼을 튼튼하게 해주는 고마운 도구예요. 속성별로 다시 묶어볼게요.


빈 칸을 막으려면 required, 글자 수는 minlength/maxlength, 정해진 형식은 pattern(정규식)이에요. 숫자·날짜 범위는 min/max/step으로 잡고요. 규칙을 어기면 브라우저가 첫 문제 칸에서 제출을 막고 말풍선을 띄워줘요. 기본 UI가 마음에 안 들면 novalidate로 끄되 규칙은 살려두고, 검증을 건너뛸 버튼엔 formnovalidate를 써요.


지금 만드는 폼의 input들을 다시 보세요. required 하나만 제대로 붙여도 "빈 값이 서버로 넘어가는" 흔한 사고를 막을 수 있어요. 브라우저가 무료로 주는 이 검증부터 야무지게 챙기고, 그걸로 부족한 부분만 자바스크립트로 채우는 게 실무의 순서예요.