<div class='content-area codepen-link'>
<p>
I see this type of input from time to time. You can see it in the wild at palces like <a href="https://disneyplus.com/begin">disneyplus.com/begin</a>. The weird part about it is that you can backspace between the fields, and copy and paste a long code into it. Not sure if there is a better way to do this style of input. If you know a way please leave a comment :)
</p>
<p>Try copying/pasting this: <code>123456</code></p>
</div>
<form onsubmit="onSubmit(event)" class="content-area">
<h4>Verify Login Code</h4>
<h5>Welcome Back!</h5>
<p>
It looks like you're trying to login from a new device.
As an added security mesure, please enter the 6-character code sent to your email.
</p>
<p><a href='#'>Need help?</a></p>
<fieldset class='number-code'>
<legend>Security Code</legend>
<div>
<input name='code' class='code-input' required/>
<input name='code' class='code-input' required/>
<input name='code' class='code-input' required/>
<input name='code' class='code-input' required/>
<input name='code' class='code-input' required/>
<input name='code' class='code-input' required/>
</div>
</fieldset>
<p><a href='#'>Resend Code</a></p>
<input type="submit" value="Submit">
</form>
*,
::before,
::after {
font-family: 'Roboto', sans-serif;
box-sizing: border-box;
margin: 0;
}
:root {
--spacing: 8px;
--hue: 400;
--background1: hsl(214, 14%, 20%);
--background2: hsl(214, 14%, 13%);
--background3: hsl(214, 14%, 5%);
--brand1: hsl(var(--hue) 80% 60%);
--text1: hsl(0,0%,100%);
--text2: hsl(0,0%,90%);
}
code {
background: var(--background3);
}
.cp-pen-embed .codepen-link {
display: none;
}
body {
display: flex;
flex-direction: column;
align-items:center;
justify-content:center;
min-height: 100vh;
background: var(--background1);
flex-gap: var(--spacing);
color: var(--text1);
gap: var(--spacing);
padding: calc(var(--spacing) * 2);
font-size: 1.5rem;
}
@media only screen and (max-width: 600px) {
body {
font-size: 1rem;
}
}
a {
color: var(--brand1);
text-decoration: none;
}
.number-code {
// overflow: auto;
> div {
display: flex;
> input:not(:last-child) {
margin-right: calc(var(--spacing) * 2);
}
}
}
.content-area {
display: flex;
flex-direction: column;
gap: calc(var(--spacing) * 2);
background: var(--background2);
padding: var(--spacing);
border-radius: var(--spacing);
max-width: min(100%, 50rem);
p {
color: var(--text2);
font-size: .8em;
}
}
form {
background-color: grey;
input.code-input {
font-size: 1.5em;
width: 1em;
text-align: center;
flex: 1 0 1em;
}
input[type='submit']{
margin-left: auto;
display: block;
font-size: 1em;
cursor: pointer;
transition: all cubic-bezier(0.4, 0.0, 0.2, 1) .1s;
&:hover {
background:var(--background3);
}
}
input{
padding: var(--spacing);
border-radius: calc(var(--spacing) / 2);
color: var(--text1);
background: var(--background1);
border: 0;
border: 4px solid transparent;
&:invalid {
box-shadow: none;
}
&:focus{
outline: none;
border: 4px solid var(--brand1);
background: var(--background3);
}
}
}
View Compiled
const inputElements = [document.querySelectorAll('input.code-input')]
inputElements.forEach((ele,index)=>{
ele.addEventListener('keydown',(e)=>{
// if the keycode is backspace & the current field is empty
// focus the input before the current. Then the event happens
// which will clear the "before" input box.
if(e.keyCode === 8 && e.target.value==='') inputElements[Math.max(0,index-1)].focus()
})
ele.addEventListener('input',(e)=>{
// take the first character of the input
// this actually breaks if you input an emoji like ๐จโ๐ฉโ๐งโ๐ฆ....
// but I'm willing to overlook insane security code practices.
const [first,rest] = e.target.value
e.target.value = first ?? '' // first will be undefined when backspace was entered, so set the input to ""
const lastInputBox = index===inputElements.length-1
const didInsertContent = first!==undefined
if(didInsertContent && !lastInputBox) {
// continue to input the rest of the string
inputElements[index+1].focus()
inputElements[index+1].value = rest.join('')
inputElements[index+1].dispatchEvent(new Event('input'))
}
})
})
// mini example on how to pull the data on submit of the form
function onSubmit(e){
e.preventDefault()
const code = inputElements.map(({value})=>value).join('')
console.log(code)
}
This Pen doesn't use any external JavaScript resources.