OTP Verification with HTML, CSS & JavaScript

30 DAYS 30 PROJECT CHALLENGE

Day #03

Project Overview

An OTP Verification system built using HTML, CSS, and JavaScript that simulates a real-world authentication flow.
When the user clicks Get OTP, a randomly generated OTP is displayed via an alert for demo purposes, and the user verifies it through a popup-based input interface. The project focuses on user interaction, input handling, and modal-based UI design.

Key Features

  • Generates a random OTP on button click.
  • Displays OTP via alert for demonstration and testing.
  • Popup (modal) based OTP input UI.
  • Auto-focus and smooth navigation between OTP input fields.
  • Validates entered OTP against the generated value.
  • Displays clear success and error messages.
  • Clean, minimal, and responsive design.
  • Beginner-friendly frontend authentication simulation.

HTML Code

<!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

* {
  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

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.