How to Create OTP Verification Code Form Using HTML, CSS and JavaScript

Categories: Forms
OTP verification code form with six input boxes UI

In this article, we will build a modern-looking OTP code verification form using HTML, CSS, and JavaScript. The form will be simple, responsive, and user-friendly. By the end of this guide, you’ll have a working OTP input form with an automatic focus shifting feature—just like you see in real-world applications.

In today’s digital world, security and authentication have become major concerns for websites and applications. Whether you are running an e-commerce store, a banking portal, or a simple membership system, email or phone-based verification using OTP (One Time Password) is one of the most secure ways to confirm a user’s identity.

Watch the Video Tutorial: OTP Verification Code Form

What You’ll Build

  • A 6-digit OTP input with separate boxes
  • Auto-move to the next box as you type
  • Backspace jumps back to the previous box
  • Paste support (paste the whole code at once—optional enhancement)
  • Clean, responsive UI with subtle accents
  • Accessible markup and mobile-friendly numeric keypad

Folder Structure

otp-form/
├─ index.html
├─ style.css
└─ script.js

HTML Code:

Here’s a semantic, accessible HTML structure. It includes an icon, a small message, and the OTP input boxes. We’ll keep the inputs as <input type="text"> so they work with all kinds of OTPs (numeric or alphanumeric).

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>OTP Code Verification Form in HTML CSS & JavaScript</title>
    <!-- ----Box Icon CDN Link------ -->
    <link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'>

    <link rel="stylesheet" href="style.css">
</head>

<body>

    <div class="opt-form">
        <div class="header-form">
            <div class="auth-icon">
                <i class="bx bxs-envelope"></i>
            </div>
            <h4>Verify Your Email</h4>
            <p>Plase Enter The Verification Code We Sent <br> To raviweb@example.com</p>
        </div>

        <form action="javascript:void(0)">
            <div class="auth-pin-wrap">
                <input type="text" class="code-input" required="">
                <input type="text" class="code-input" required="">
                <input type="text" class="code-input" required="">
                <input type="text" class="code-input" required="">
                <input type="text" class="code-input" required="">
                <input type="text" class="code-input" required="">
            </div>

            <div class="btn-wrap">
                <button type="submit">Confirm</button>
            </div>
        </form>
    </div>

    <!-- =====================JavaScript============== -->
    <script src="script.js"></script>

</body>

</html>

Explanation:

  • The form is wrapped inside a div.opt-form.
  • Six input fields are used for six OTP digits.
  • Each input accepts only one digit (we use maxlength="1").
  • The confirm button will handle OTP submission.
  • aria-labels and role improve screen-reader support.

CSS Code:

Now let’s make the form visually appealing with CSS.

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: Arial, Helvetica, sans-serif;
    background: linear-gradient(75.95deg, #7667FF 0.41%, #483FF3 98.9%);
    height: 100vh;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    padding: 15px;
}

.opt-form {
    width: 100%;
    max-width: 550px;
    margin: 0 auto;
    padding: 20px 30px;
    background: #fff;
    border-radius: 10px;
    box-shadow: 0 0 35px rgba(0, 0, 0, 0.1);
    position: relative;
    z-index: 999;
}

.header-form {
    text-align: center;
    margin-bottom: 35px;
}

.auth-icon {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: rgba(41, 128, 185, 0.1);
    margin: 0 auto 20px;
}

.auth-icon i {
    font-size: 35px;
    color: #7667FF;
}

.header-form h4 {
    margin-bottom: 5px;
    font-size: 20px;
    font-weight: 700;
    text-transform: capitalize;
}

.header-form p {
    font-size: 16px;
    color: #040404;
}

.auth-pin-wrap {
    display: flex;
    align-items: center;
    margin-bottom: 45px;
}

.auth-pin-wrap .code-input {
    width: 100%;
    min-height: 50px;
    text-align: center;
    font-size: 20px;
    font-weight: 600;
    color: #040404;
    border-color: #e8e8e8;
    border: 1px solid #ced4da;
    border-radius: 5px;
    outline: none;
}

.auth-pin-wrap .code-input:focus {
    border: 1px solid #7667FF;
}

.auth-pin-wrap .code-input:nth-child(n+2) {
    margin-left: 15px;
}

.btn-wrap button {
    width: 100%;
    padding: 15px 30px;
    border-radius: 8px;
    background-color: #7667FF;
    color: #fff;
    border: 1px solid #7667FF;
    font-size: 18px;
    font-weight: 500;
    cursor: pointer;
}

@media(max-width:475px) {
    .auth-pin-wrap .code-input:nth-child(n+2) {
        margin-left: 5px;
    }
}

Key Points:

  • Gradient background for a modern look.
  • Centered container with shadow and rounded corners.
  • Input boxes styled big and bold for readability.
  • Responsive design for mobile devices.

JavaScript Code:

This script does three helpful things:

  1. Auto-advance to the next box as you type.
  2. Smart backspace: if a box is empty and you press Backspace, focus moves to the previous box.
  3. Paste support: paste a full 6-digit code and it fills all boxes instantly.
const inputElement = [...document.querySelectorAll("input.code-input")];
inputElement.forEach((elem, index) => {
  elem.addEventListener("keydown", (e) => {
    if (e.keyCode === 8 && e.target.value === "") {
      inputElement[Math.max(0, index - 1)].focus();
    }
  });

  elem.addEventListener("input", (e) => {
    const [first, ...rest] = e.target.value;
    e.target.value = first ?? "";
    const lastInputBox = index === inputElement.length - 1;
    const insertedContent = first !== undefined;
    if (insertedContent && !lastInputBox) {
      inputElement[index + 1].focus();
      inputElement[index + 1].value = rest.join("");
      inputElement[index + 1].dispatchEvent(new Event("input"));
    }
  });
});

 How It Works:

  • keydown event: detects Backspace. If the current input is empty, it moves focus back to the previous field.
  • input event: ensures each input box only holds one character. If more characters are pasted, they are automatically distributed to the next boxes.
  • Cursor automatically shifts forward after typing a digit.

Output Preview

Once you implement the above code, your form will look like this:

Screen:

  • A centered card with 6 input boxes.
  • A nice icon above form.
  • Responsive OTP input flow (like Gmail, WhatsApp).

Practical Use Cases

You can integrate this OTP input form in:

  • Login & Signup verification
  • Two-factor authentication (2FA) systems
  • Password reset pages
  • Secure checkout pages

Remember: This tutorial focuses on the front-end part. For real-world OTP, you’ll need to connect with a server (backend) that sends emails or SMS using services like Twilio, SendGrid, Firebase, or AWS SES.

Conclusion

We have successfully created a professional OTP verification code form using HTML, CSS, and JavaScript. This small project is not only a great UI practice but also a building block for more secure applications.

Beginner developers can learn DOM manipulation, event handling, and UI styling from this tutorial.

Advanced developers can integrate it into their real backend authentication system.

Live Demo