One-time code
A one-time code input splits a short numeric code across several boxes so each digit is visible and easy to check. It is built for codes from SMS or email.
<input inputmode="numeric" maxlength="1">Also called OTP input, Verification code, PIN boxes.
Sent to •••• 4821. Resend in 0:42.
0 of 6 digits
Type six digits. Focus moves to the next box automatically. Paste a full code from an SMS and it fills every slot.
For designers
A one-time code field is tuned for a moment everyone has lived through: confirm the account, check the phone, type six digits, submit. Splitting the code across boxes makes typos visible and matches what people see in the SMS.
The cost is implementation. Focus management, paste, mobile keyboards and error states need more care than a single input. If the code is eight characters and mixed letters and numbers, one text field is the simpler choice.
Put resend and expiry copy near the field, not on a separate screen. Sent to •••• 4821 and Resend in 0:42 belong with the boxes so someone waiting for a message knows the code is on its way.
When to use an one-time code
Use an one-time code when
- Someone receives a fixed-length numeric code and must type it once
- Showing each digit in its own box helps catch typos before submit
- Paste from an SMS should fill every box in one action
Reach for something else when
- The value is free text, like a password with letters and symbols. Use a text field instead.
- The code is long or alphanumeric and does not fit a fixed digit pattern. Use a text field instead.
- Someone types a single long number like a card or account number. Use a text field instead.
- The same digits open the device every day as a PIN. Use a masked PIN field instead.
Variants
Four digits for a PIN, and six with a separator in the middle the way many SMS codes arrive.
Six digits. The default for SMS verification. No separator, or a dash in the middle when the message formats that way.
Four-digit PIN. Shorter boxes for device or card PIN entry when the flow is numeric only.
With separator. A visual break between the third and fourth digit. Cosmetic only; paste should still accept the full string without the dash.
How to build a one-time code
Use one hidden input or several single-character fields wired as one group. Expose a single label and announce the group as one field.
<label for="otp-1">Verification code</label>
<div role="group" aria-labelledby="otp-1">
<input id="otp-1" inputmode="numeric" maxlength="1" aria-label="Digit 1 of 6" />
<input inputmode="numeric" maxlength="1" aria-label="Digit 2 of 6" />
<input inputmode="numeric" maxlength="1" aria-label="Digit 3 of 6" />
<input inputmode="numeric" maxlength="1" aria-label="Digit 4 of 6" />
<input inputmode="numeric" maxlength="1" aria-label="Digit 5 of 6" />
<input inputmode="numeric" maxlength="1" aria-label="Digit 6 of 6" />
</div>
<p id="otp-hint">Sent to your phone. Resend in 0:42.</p>
inputmode="numeric" brings up a number pad on phones. On input, advance focus forward. On Backspace in an empty box, go back. Listen for paste on the group and split digits across slots. Submit when all boxes are full or when the person presses Enter.
Autofill from SMS is increasingly common on mobile browsers. Keep one logical field in the accessibility tree even when the paint shows six boxes, so autofill can target the right control.
Edge cases
Wrong code. Clear the boxes or mark them invalid together. One error on the group beats six red rings with no explanation.
Auto-submit. Submit when the last digit arrives only if failure recovery is obvious. A wrong digit should be easy to fix without reloading the page.
Rate limiting. Pair the field with lockout or delay copy after several failures. Say how many tries remain.
Separator in the message. If the SMS shows 482-910, paste should still accept digits with or without the dash.
Accessibility on desktop. Six boxes mean six tab stops if you wire them as separate inputs. Consider one hidden input that receives focus first on mobile autofill, with visual slots updated from its value.
Common questions
- One-time code or one text field?
- Separate boxes help for six-digit SMS codes where people want to verify each digit. One field is simpler for alphanumeric backup codes. Banks and Stripe-style verification flows use boxes because the length is fixed and numeric.
- How many boxes?
- Match the code length exactly. Six is common for SMS. Four suits some PIN flows. Do not add extra empty boxes.
- Should paste work?
- Yes. Pasting 482910 from a message should distribute across slots without extra clicks. This is the feature people notice most when it is missing.
- What about auto-advance?
- Move focus to the next box when a digit is entered. On Backspace in an empty box, move to the previous box and clear it.
- Is masking required?
- Usually no for a one-time code that expires in minutes. Masking suits a reusable PIN. Show digits for OTP unless policy says otherwise.
- How do I handle resend?
- Offer Resend code with a visible cooldown timer. Clear the boxes when a new code is sent so old digits do not linger.
Last reviewed 27 AUG 2026