✅ 폼 유효성 검사

폼 유효성 검사
완전 정복

사용자가 잘못된 정보를 입력했을 때 서버로 보내기 전에 미리 걸러내는 방법. HTML5 속성부터 JavaScript 실시간 검사, 비밀번호 강도 표시까지 — 바이브 코딩으로 회원가입 폼을 완성해 봅시다.

📄 HTML5 + Vanilla JS ⚡ 실시간 피드백 🔐 비밀번호 강도 체크 📋 복사 가능한 코드
① Concept

폼 유효성 검사란?

사용자가 입력한 값이 올바른지 서버로 보내기 전에 미리 확인하는 과정이에요. 잘못된 이메일, 짧은 비밀번호, 빈칸 제출을 막아 서버 부담을 줄이고 사용자 경험을 높여줍니다.

💡

왜 필요한가요? 서버는 데이터베이스에 저장하기 전에 값을 검증하지만, 그 전에 클라이언트(브라우저)에서 한 번 더 걸러주면 불필요한 네트워크 요청이 줄고 사용자는 즉각적인 피드백을 받을 수 있어요.

🖥️

클라이언트 사이드 검사

브라우저에서 바로 실행돼요. 서버 요청 없이 즉각 피드백을 줄 수 있어 UX가 좋아요. 단, JavaScript를 끄거나 개발자 도구로 우회할 수 있어 보안 검사로는 사용하면 안 돼요.

🔒

서버 사이드 검사

서버에서 직접 검증해요. 우회가 불가능하므로 보안과 데이터 무결성에 필수예요. 클라이언트 검사는 편의를 위한 것이고, 실제 보안은 반드시 서버에서 담당해야 해요.

🏷️

HTML5 기본 검사

required, type="email", minlength, pattern 속성만으로도 기본 검사가 가능해요. 단, 에러 메시지 커스터마이징이나 실시간 피드백은 JavaScript가 필요해요.

JavaScript 커스텀 검사

입력 중 실시간으로 검사(input 이벤트), 포커스 벗어날 때 검사(blur 이벤트), 제출 시 최종 검사(submit 이벤트) 등 세밀한 타이밍 제어와 맞춤 메시지가 가능해요.

방식 실행 위치 실시간 피드백 커스텀 메시지 보안
HTML5 속성 브라우저 제출 시만 제한적 우회 가능
JS 클라이언트 브라우저 가능 자유롭게 우회 가능
서버 사이드 서버 응답 후 자유롭게 우회 불가
② Types

유형별 검사 방법

실무에서 가장 자주 쓰이는 네 가지 검사 유형이에요. 각 카드의 입력창에 직접 타이핑해서 결과를 확인해 보세요.

✏️

필수 입력 검사

빈칸으로 제출하는 것을 막아요. 가장 기본적인 검사예요.

if (value.trim() === '') { // 빈칸 → 에러 showError('필수 입력 항목이에요'); }
📧

이메일 형식 검사

@ 기호와 도메인(.com 등)이 올바르게 포함됐는지 정규식으로 확인해요.

const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!re.test(value)) { showError('이메일 형식이 맞지 않아요'); }
🔐

비밀번호 강도 검사

최소 8자, 영문 + 숫자 포함 여부를 확인해요.

const hasLetter = /[a-zA-Z]/.test(v); const hasNumber = /[0-9]/.test(v); if (v.length < 8 || !hasLetter || !hasNumber) { showError('8자 이상, 영문+숫자 필수'); }
🔁

두 필드 일치 검사

비밀번호 확인처럼 두 입력값이 같은지 비교해요.

const pw1 = document.getElementById('pw').value; const pw2 = document.getElementById('pw-confirm').value; if (pw1 !== pw2) { showError('비밀번호가 일치하지 않아요'); }
③ Code

코드 해설

폼 유효성 검사에 필요한 HTML 구조, CSS 상태 스타일, JavaScript 로직을 단계별로 살펴봐요.

1단계 — HTML 구조

각 필드를 .field-wrap으로 감싸고, 메시지를 표시할 .field-msg를 아래에 붙여요.

index.html
<!-- HTML 구조 -->
<form id="signup-form">
  <div class="field-wrap">
    <label for="email">이메일</label>
    <input type="email" id="email"
           placeholder="example@email.com">
    <!-- 검사 결과 메시지가 여기 표시돼요 -->
    <span class="field-msg" id="email-msg"></span>
  </div>

  <div class="field-wrap">
    <label for="password">비밀번호</label>
    <input type="password" id="password"
           placeholder="8자 이상, 영문+숫자">
    <span class="field-msg" id="pw-msg"></span>
  </div>

  <button type="submit">가입하기</button>
</form>

2단계 — CSS 검사 상태 스타일

JavaScript가 .valid 또는 .invalid 클래스를 붙이면 아래 CSS가 테두리 색을 바꿔요.

style.css
/* 검사 상태 스타일 */
.field-wrap input.valid {
  border-color: #16a34a; /* 초록 — 통과 */
  background: #f0fdf4;
}
.field-wrap input.invalid {
  border-color: #e11d48; /* 빨강 — 오류 */
  background: #fff1f2;
}

/* 메시지 색상 */
.field-msg.ok  { color: #16a34a; }
.field-msg.err { color: #e11d48; }

3단계 — JavaScript 실시간 검사

input 이벤트로 타이핑할 때마다 검사하고, setValid() 헬퍼로 클래스와 메시지를 한 번에 설정해요.

script.js
// 공통 헬퍼 함수
function setValid(input, msgId, isOk, okMsg, errMsg) {
  const msg = document.getElementById(msgId);
  input.classList.toggle('valid',   isOk);
  input.classList.toggle('invalid', !isOk);
  msg.textContent = isOk ? okMsg : errMsg;
  msg.className = 'field-msg ' + (isOk ? 'ok' : 'err');
}

// 이메일 실시간 검사
document.getElementById('email')
  .addEventListener('input', function() {
    const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    setValid(
      this, 'email-msg',
      re.test(this.value),
      '올바른 이메일 형식이에요',
      '이메일 형식이 맞지 않아요'
    );
  });

// 비밀번호 실시간 검사
document.getElementById('password')
  .addEventListener('input', function() {
    const v = this.value;
    const ok = v.length >= 8
               && /[a-zA-Z]/.test(v)
               && /[0-9]/.test(v);
    setValid(
      this, 'pw-msg', ok,
      '안전한 비밀번호예요',
      '8자 이상, 영문+숫자를 포함해주세요'
    );
  });

// 제출 시 최종 검사
document.getElementById('signup-form')
  .addEventListener('submit', function(e) {
    e.preventDefault(); // 실제 전송 막기
    // 각 필드 검사 후 모두 통과 시 서버로 전송
  });
④ Demo

직접 체험해 보세요

아래 폼은 실제로 동작하는 회원가입 폼이에요. 각 필드에 입력하면 즉시 초록/빨간 피드백이 나오고, 모든 항목을 통과해야 가입 버튼이 활성화돼요.

signup-form.html — 라이브 데모
회원가입
모든 항목을 올바르게 입력하면 가입 버튼이 활성화돼요.
⑤ Prompt Tip

AI 프롬프트 팁

바이브 코딩할 때 AI에게 폼 유효성 검사를 요청하는 가장 효과적인 방법이에요. 아래 프롬프트를 복사해서 그대로 붙여넣어 보세요.

✦ 바이브코더 프롬프트

회원가입 폼에 실시간 유효성 검사를 추가하고 싶다면 아래 프롬프트를 AI에게 주세요. 구체적으로 요구할수록 완성도 높은 코드를 받을 수 있어요.

내 사이트 회원가입 폼에 실시간 유효성 검사를 추가해줘.

요구사항:
- 이름: 2자 이상
- 이메일: 형식 확인 (@ 포함, 도메인 포함)
- 비밀번호: 8자 이상, 영문+숫자 필수
- 비밀번호 확인: 위 비밀번호와 일치해야 함

동작 방식:
- 각 필드 입력 중 실시간으로 에러/성공 메시지 표시
- 통과한 필드는 초록 테두리, 실패한 필드는 빨간 테두리
- 모든 필드 통과 시에만 제출 버튼 활성화
- 제출 시 전체 재검사 후 성공 토스트 메시지 표시

기술 조건:
- 순수 HTML + CSS + Vanilla JS (라이브러리 없이)
- 단일 HTML 파일로 완성
💬

팁: "라이브러리 없이"를 명시하면 jQuery나 외부 validation 라이브러리 없이 바닐라 JS로만 구현된 깔끔한 코드를 받을 수 있어요. 프레임워크(React, Vue 등)를 쓴다면 해당 프레임워크명도 함께 적어주세요.

⑥ FAQ

자주 묻는 질문

폼 유효성 검사를 처음 구현할 때 헷갈리는 부분들을 정리했어요.

required만 쓰면 브라우저 기본 에러 메시지가 나와요. 이 메시지는 브라우저마다 모양이 다르고, 한국어로 바꾸기 어려우며, 제출 전에 실시간 피드백을 줄 수 없어요. 사용자 경험을 높이려면 JavaScript로 커스텀 검사를 추가하는 것이 좋아요.
정규식(Regular Expression)은 문자 패턴을 표현하는 규칙이에요. 이메일의 @ 포함 여부, 전화번호의 숫자+하이픈 형식처럼 복잡한 패턴을 한 줄로 표현할 수 있어요. AI에게 "이메일 검사 정규식 만들어줘"라고 하면 바로 코드를 받을 수 있어서 외울 필요는 없어요.
네, 반드시 서버에서도 검사해야 해요. 브라우저 JavaScript는 개발자 도구나 직접 API 요청으로 완전히 우회할 수 있어요. 클라이언트 검사는 사용자 편의와 서버 부담 감소를 위한 것이고, 실제 보안과 데이터 무결성은 서버 사이드 검사가 담당해야 해요.
input의 type 속성을 passwordtext 사이에서 전환하면 돼요. 눈 모양 아이콘 버튼을 만들고, 클릭할 때마다 input.type = input.type === 'password' ? 'text' : 'password'를 실행하면 간단하게 구현할 수 있어요.
UX에 따라 달라요. 비활성화 버튼은 "왜 클릭이 안 되지?" 하는 혼란을 줄 수 있어요. 대신 버튼은 항상 활성화하되, 클릭 시 모든 필드를 검사하고 오류를 한 번에 표시하는 방식도 자주 쓰여요. 이 페이지의 데모는 학습 목적으로 비활성화 방식을 사용했어요.