본문 바로가기
명함 만들기 캐릭터 모음 16가지 디자인 · PNG / SVG / PDF

인증번호 확인 화면

문자를 기다리는 동안 사람이 가장 많이 이탈하는 화면 — 남은 시간과 다시 받는 길을 숨기지 말아야 한다.

폼 · 패턴

실제 미리보기

출처

<form class="dc-vc" action="#">
  <header class="dc-vc__bar">
    <button class="dc-vc__back" type="button">
      <span aria-hidden="true">‹</span><span class="dc-sr">뒤로</span>
    </button>
    <h1 class="dc-vc__bartitle">인증번호 확인</h1>
  </header>
  <div class="dc-vc__body">
    <p class="dc-vc__lead">문자로 보낸 6자리를 넣어 주세요</p>
    <p class="dc-vc__to">010-1234-5678 <a class="dc-vc__edit" href="#">번호 수정</a></p>
    <fieldset class="dc-vc__set">
      <legend class="dc-sr">인증번호 6자리</legend>
      <div class="dc-vc__cells">
        <input class="dc-vc__cell" type="text" inputmode="numeric" autocomplete="one-time-code" maxlength="1" value="4" aria-label="인증번호 1번째 자리" />
        <input class="dc-vc__cell" type="text" inputmode="numeric" maxlength="1" value="9" aria-label="인증번호 2번째 자리" />
        <input class="dc-vc__cell" type="text" inputmode="numeric" maxlength="1" value="1" aria-label="인증번호 3번째 자리" />
        <input class="dc-vc__cell" type="text" inputmode="numeric" maxlength="1" value="" aria-label="인증번호 4번째 자리" />
        <input class="dc-vc__cell" type="text" inputmode="numeric" maxlength="1" value="" aria-label="인증번호 5번째 자리" />
        <input class="dc-vc__cell" type="text" inputmode="numeric" maxlength="1" value="" aria-label="인증번호 6번째 자리" />
      </div>
    </fieldset>
    <div class="dc-vc__foot">
      <span class="dc-vc__timer">2:43 남음</span>
      <button class="dc-vc__resend" type="button">다시 받기</button>
    </div>
    <p class="dc-vc__note">문자가 오지 않으면 스팸 차단 설정을 확인하고, 그래도 안 오면 번호를 다시 확인하세요.</p>
  </div>
  <div class="dc-vc__bottom">
    <button class="dc-vc__submit" type="submit">확인</button>
  </div>
</form>
.dc-vc { display:flex; flex-direction:column; height:580px; overflow:hidden; background:var(--dc-bg); border:1px solid var(--dc-line); border-radius:var(--dc-r-md); font-family:var(--dc-font); }
.dc-vc__bar { flex:0 0 auto; display:flex; align-items:center; gap:var(--dc-1); padding:calc(var(--dc-safe-top) + var(--dc-2)) var(--dc-2) var(--dc-2); background:var(--dc-surface); border-bottom:1px solid var(--dc-line); }
.dc-vc__back { flex:0 0 auto; display:grid; place-items:center; width:44px; height:44px; border:0; border-radius:var(--dc-r-full); background:transparent; color:var(--dc-text); font-size:22px; line-height:1; }
.dc-vc__back:active { background:var(--dc-sunken); }
.dc-vc__bartitle { margin:0; font-size:16px; font-weight:700; color:var(--dc-text); }
.dc-vc__body { flex:1 1 auto; min-height:0; overflow-y:auto; padding:var(--dc-5) var(--dc-4); }
.dc-vc__lead { margin:0 0 var(--dc-1); font-size:19px; font-weight:800; letter-spacing:-.02em; line-height:1.4; color:var(--dc-text); }
.dc-vc__to { display:flex; align-items:center; gap:var(--dc-2); margin:0 0 var(--dc-4); font-size:14px; color:var(--dc-text-sub); }
.dc-vc__edit { display:inline-flex; align-items:center; min-height:44px; color:var(--dc-brand-text); font-size:13px; font-weight:700; }
.dc-vc__set { min-width:0; margin:0; padding:0; border:0; }
.dc-vc__cells { display:flex; gap:var(--dc-2); }
.dc-vc__cell { flex:1 1 0; min-width:0; height:56px; padding:0; border:1px solid var(--dc-line-field); border-radius:var(--dc-r-sm); background:var(--dc-surface); color:var(--dc-text); font-family:var(--dc-mono); font-size:24px; font-weight:700; text-align:center; }
.dc-vc__cell:focus { outline:none; border-color:var(--dc-brand); box-shadow:0 0 0 3px var(--dc-brand-soft); }
.dc-vc__cell.is-error { border-color:var(--dc-danger); background:var(--dc-danger-soft); color:var(--dc-danger); }
.dc-vc__err { display:flex; gap:var(--dc-2); margin:var(--dc-3) 0 0; font-size:13px; font-weight:700; line-height:1.5; color:var(--dc-danger); }
.dc-vc__foot { display:flex; align-items:center; justify-content:space-between; gap:var(--dc-3); margin-top:var(--dc-4); }
.dc-vc__timer { font-family:var(--dc-mono); font-size:14px; color:var(--dc-text-sub); }
.dc-vc__timer--out { color:var(--dc-danger); font-weight:700; }
.dc-vc__resend { min-height:44px; padding:0 var(--dc-4); border:1px solid var(--dc-line-field); border-radius:var(--dc-r-sm); background:var(--dc-surface); color:var(--dc-text); font-family:inherit; font-size:14px; font-weight:700; }
.dc-vc__resend:active { background:var(--dc-sunken); }
.dc-vc__resend--go { border-color:var(--dc-brand); background:var(--dc-brand-soft); color:var(--dc-brand-text); }
.dc-vc__note { margin:var(--dc-5) 0 0; font-size:12px; line-height:1.7; color:var(--dc-text-mute); }
.dc-vc__bottom { flex:0 0 auto; padding:var(--dc-3) var(--dc-4) calc(var(--dc-safe-bottom) + var(--dc-3)); background:var(--dc-surface); border-top:1px solid var(--dc-line); }
.dc-vc__submit { width:100%; min-height:52px; border:0; border-radius:var(--dc-r-sm); background:var(--dc-brand); color:var(--dc-text-on); font-family:inherit; font-size:16px; font-weight:700; }
.dc-vc__submit:active { background:var(--dc-brand-hi); }
.dc-vc__submit[disabled] { background:var(--dc-sunken); color:var(--dc-text-mute); }

이렇게 씁니다

  • 보낸 번호를 화면에 그대로 적고 번호 수정 링크를 옆에 둔다 — 잘못 적었는지 여기서 깨닫는다
  • 남은 시간과 다시 받기 버튼을 칸 바로 아래에 같이 둔다
  • 시간이 지나면 칸을 잠그고 다시 받기를 주 버튼처럼 강조한다
  • autocomplete=one-time-code 로 문자에서 바로 채워지게 한다

주의할 점

  • 칸마다 몇 번째 자리인지 aria-label 을 붙인다 — 빈 칸 여섯 개에는 읽어 줄 이름이 없다
  • 틀렸을 때 칸만 빨갛게 만들지 말고 role=alert 로 이유를 읽어 준다
  • 하단 고정 버튼에 --dc-safe-bottom 을 빼면 아이폰 홈 바에 가려 눌리지 않는다

다음에 볼 것