OTP Code Input
Six-box one-time-code field over a single native input: each digit lands with a bounce, a ring slides to the next box, a paste fills every box in sequence and a wrong code shakes and clears.
About This Component
A six-box verification code field that behaves the way people expect one to. Each digit lands in its box with an elastic bounce while a ring slides on to the next, Backspace steps the ring back and lifts the character out, and pasting a whole code fills the row one box after another rather than all at once. Get it wrong and the row shakes and empties itself; get it right and the boxes turn green in sequence.
Read the full effect overview
Underneath there is exactly one real input, laid transparently across the row. That single field is the value, the caret, the paste target and the whole keyboard behaviour, so autofill of an SMS code, select-all, undo and form submission all work without a line of code holding them up. Ships in three looks, vault, glass and paper, switched with one data-variant attribute.
What's Included
- Elastic bounce on each box as its character lands
- Sliding focus ring measured from the boxes, so any gap or size works
- Backspace steps the ring back and lifts the character out
- Pasted codes fill every box with a stagger instead of appearing at once
- Wrong code shakes the row, colours it and clears itself
- Right code turns the boxes green one after another
- One native input holds the value for forms, autofill and screen readers
- Non-digits are stripped as they arrive, and the length is capped by the box count
- Three shipped variants: vault, glass, paper
Perfect For
- Two-factor and login verification screens
- Email or SMS confirmation steps in sign-up flows
- Payment and transfer confirmation prompts
- Any short code a person has to copy from somewhere else
How It Works
One input, six boxes
The boxes are aria-hidden decoration drawn under a single transparent input that covers the whole row. Every keystroke, paste and autofill goes to that input, and a single input listener diffs its value against what is drawn and animates only the characters that actually changed.
Bounce, slide, stagger
A landing character springs in with back.out while its box bounces with elastic.out. The ring is moved by x measured from each box's rectangle rather than by a CSS offset, so it lands correctly whatever the gap or box size. A jump of more than one character is treated as a paste and the landings are staggered.
Right and wrong
Reaching the full length compares the value against the code on the wrapper. Wrong shakes the boxes with an elastic x and empties the field half a second later; right cross-fades the boxes to the success colour with a stagger. Both colours are read from custom properties with getComputedStyle at the moment the tween is built.