OTP Verification with HTML, CSS & JavaScript

30 DAYS 30 PROJECT CHALLENGE

Day #03

Project Overview

OTP Verification is an beginner-friendly project built using HTML, CSS, and JavaScript. It simulates a simple authentication process by generating a random four-digit One-Time Password (OTP) when the user clicks the Get OTP button. For demonstration purposes, the generated OTP appears in an alert box. After receiving the OTP, user is required to enter the given OTP in the input fields. On submitting the JavaScript code matches the submitted OTP with the created OTP and displays a message of either success or failure. 

This project is useful for beginners who want to practice JavaScript events, random number generation, DOM manipulation, input handling, conditional statements, and modal-based user interfaces. It also demonstrates the basic frontend logic behind an OTP verification system.

Key Features

  • Random OTP Generation: By clicking on the Get OTP button, the user is allowed to generate a random 4-digit OTP. For this purpose, a function is used in JavaScript to get the value every time a user initiates the verification process.
  • OTP Demo Alert: For demonstration and testing purposes, the generated OTP is displayed in an alert box. This allows users to see the OTP before entering it into the verification fields.
  • Popup Verification Interface: Instead of having the verification fields permanently on the page, they are placed in a popup modal. In such a way, a simplified interface is provided to the end-user.
  • Four Separate OTP Fields: The user is required to input the 4-digit OTP in 4 separate fields. Each field only accepts one character which provides a familiar OTP verification experience.
  • Automatic Input Focus: After the user inputs a digit, the focus moves automatically to the next field. This way, there is no need for the user to tab from one field to another.
  • Backspace Navigation: By pressing the Backspace key in an empty field, the user can move to the previous OTP verification field.
  • OTP Validation: After the user has finished inputting the OTP, it is validated by concatenating all 4 fields values and comparing it to the randomly generated OTP. The validation is done with JavaScript.
  • Success and Error Messages: After clicking the Verify OTP button, the end-user is notified of a successful or failed verification. In both cases, a system message is displayed.
  • Modal Close Button: Finally, the modal includes a close button which allows the user to close the OTP verification modal without verification.
  • Clean and Responsive Design: The project uses a simple interface with a centered button, modal popup, clearly visible input fields, and responsive styling that works comfortably on different screen sizes.

What You'll Learn

  • Understand how to generate random numbers using Math.random().
  • Learn how JavaScript can create a four-digit OTP.
  • Practice selecting HTML elements using getElementById() and querySelectorAll().
  • Learn how to show and hide a modal using JavaScript.
  • Understand how event listeners respond to user input.
  • Practice automatically moving focus between input fields.
  • Learn how keyboard events can improve user interaction.
  • Understand how to combine values from multiple input fields.
  • Practice using conditional statements to validate user input.
  • Learn how to display success and error messages dynamically.
  • Understand how HTML, CSS, and JavaScript work together to create an authentication-style interface.

HTML Code

HTML creates the structure of the OTP Verification application. First, the style.css file is linked inside the <head> section so CSS can control the appearance and layout of the project. The main page contains a Get OTP button, which starts the OTP generation process when clicked. The OTP verification interface is placed inside the .modal container, this modal remains hidden until JavaScript displays it after generating an OTP. Inside the modal, the .modal-box contains the heading, instructions, four OTP input fields, the Verify OTP button, and a message area.

Each OTP input uses maxlength="1", allowing users to enter only one character in each field. The close icon calls the closeModal() function, while the Verify OTP button calls verifyOTP(). Finally, the script.js file is loaded at the bottom of the <body> so JavaScript can access the required elements and add the application’s functionality.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>OTP Verification Demo</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>

  <button class="btn" onclick="handleGetOTP()">Get OTP</button>

  <!-- Modal -->
  <div class="modal" id="modal">
    <div class="modal-box">
      <span class="close" onclick="closeModal()">×</span>

      <h3>Enter OTP</h3>
      <p>Please enter the 4-digit OTP</p>

      <div class="otp-box">
        <input maxlength="1">
        <input maxlength="1">
        <input maxlength="1">
        <input maxlength="1">
      </div>

      <button class="btn" onclick="verifyOTP()">Verify OTP</button>
      <p class="msg" id="msg"></p>
    </div>
  </div>

  <script src="script.js"></script>
</body>
</html>

CSS Code

CSS controls the appearance and layout of the OTP Verification project. The body uses Flexbox to place the Get OTP button in the center of the page, while the minimum height ensures that the layout covers the full screen. The .btn class styles the main action buttons by adding padding, rounded corners, font sizing, and a pointer cursor, .modal class creates the popup overlay and remains hidden until JavaScript changes its display property, .modal-box styles the OTP popup with a white background, fixed width, padding, rounded corners, and centered content, .otp-box class uses Flexbox to arrange the four input fields in a row with proper spacing.

Each OTP input receives a fixed width and height, centered text, borders, and rounded corners, :focus selector changes the border color when an input field becomes active. Finally, the .msg class provides space for verification messages below the button.

* {
  box-sizing: border-box;
  font-family: Arial, sans-serif;
}

body {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #042453;
}

.btn {
  padding: 14px 28px;
  border: none;
  border-radius: 8px;
  background: #fff;
  cursor: pointer;
  font-size: 16px;
}

/* Modal */
.modal {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  justify-content: center;
  align-items: center;
}

.modal-box {
  background: #fff;
  width: 300px;
  padding: 25px;
  border-radius: 12px;
  text-align: center;
  position: relative;
}

.close {
  position: absolute;
  right: 12px;
  top: 8px;
  font-size: 22px;
  cursor: pointer;
}

.otp-box {
  display: flex;
  justify-content: space-between;
  margin: 20px 0;
}

.otp-box input {
  width: 50px;
  height: 50px;
  font-size: 18px;
  text-align: center;
  border-radius: 6px;
  border: 1px solid #ccc;
}

.otp-box input:focus {
  outline: none;
  border-color: #4f46e5;
}

.msg {
  margin-top: 10px;
  font-size: 14px;
}

Javascript Code

JavaScript handles the main functionality of the OTP Verification application. First, it selects the modal, OTP input fields, and message element from the HTML, otp variable stores the randomly generated verification code. When the user clicks Get OTP, the handleGetOTP() function generates a random four-digit number using Math.random(), generated OTP appears in an alert for demonstration purposes. After that, JavaScript opens the modal, clears any previous input values, and automatically focuses on the first OTP field.

Event listeners are added to each input field to improve navigation. After a user enters a digit, the focus moves to the next field. If the user presses Backspace in an empty field, the focus returns to the previous input, verifyOTP() function combines the values entered into the four fields and checks whether the OTP is complete. It then compares the entered value with the generated OTP. If both values match, a success message appears before the modal closes. Otherwise, the application displays an appropriate error message.

const modal = document.getElementById("modal");
const inputs = document.querySelectorAll(".otp-box input");
const msg = document.getElementById("msg");

let otp = "";

/* Generate OTP & Show Alert */
function handleGetOTP() {
  otp = Math.floor(1000 + Math.random() * 9000).toString();
  alert("Your OTP is: " + otp);

  modal.style.display = "flex";
  msg.innerText = "";
  inputs.forEach(i => i.value = "");
  inputs[0].focus();
}

/* Close Modal */
function closeModal() {
  modal.style.display = "none";
}

/* Auto focus */
inputs.forEach((input, index) => {
  input.addEventListener("input", () => {
    if (input.value && index < inputs.length - 1) {
      inputs[index + 1].focus();
    }
  });

  input.addEventListener("keydown", e => {
    if (e.key === "Backspace" && !input.value && index > 0) {
      inputs[index - 1].focus();
    }
  });
});

/* Verify OTP */
function verifyOTP() {
  let enteredOTP = "";
  inputs.forEach(i => enteredOTP += i.value);

  if (enteredOTP.length < 4) {
    msg.style.color = "red";
    msg.innerText = "Enter complete OTP";
    return;
  }

  if (enteredOTP === otp) {
    msg.style.color = "green";
    msg.innerText = "OTP Verified ✅";

    setTimeout(() => {
      closeModal();
      alert("Verification Successful 🎉");
    }, 800);
  } else {
    msg.style.color = "red";
    msg.innerText = "Invalid OTP ❌";
  }
}
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Related Projects

Day 8 : Star Rating Component

Interactive star-based rating UI with hover and click functionality.

Concepts: User interaction, dynamic styling, state handling.

Day 9 : Notification Toast System

Displays temporary notifications with auto-dismiss and manual close support.

Concepts: Dynamic UI updates, timed interactions, visual feedback.

Day 10 : Skeleton Loader (Shimmer Effect)

Displays animated placeholders while content is loading.

Concepts: Loading states, shimmer animation, UI feedback, conditional rendering.