Multi-Step Form (Progress Based) with HTML, CSS & JavaScript

30 DAYS 30 PROJECT CHALLENGE

Day #02

Project Overview

A Multi-Step Form built using HTML, CSS, and JavaScript that guides users through a form in multiple steps with a visual progress indicator.
The project focuses on improving user experience by breaking long forms into manageable sections while validating inputs at each step and updating progress in real time.

Key Features

  • Step-by-step form layout with progress bar tracking.
  • Next and Previous navigation between form steps.
  • Input validation before moving to the next step.
  • Real-time progress update based on current step.
  • Prevents submission until all required fields are completed.
  • Clean, minimal, and responsive UI.
  • Improves usability for long or complex forms.

HTML Code

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

  <div class="form-container">
    <h2>Multi-Step Form</h2>

    <!-- Progress Bar -->
    <div class="progress-bar">
      <div class="progress" id="progress"></div>
    </div>

    <form id="multiStepForm">

      <!-- Step 1 -->
      <div class="step active">
        <label>Full Name</label>
        <input type="text" id="name" />
      </div>

      <!-- Step 2 -->
      <div class="step">
        <label>Email</label>
        <input type="email" id="email" />
      </div>

      <!-- Step 3 -->
      <div class="step">
        <label>Password</label>
        <input type="password" id="password" />
      </div>

      <!-- Buttons -->
      <div class="buttons">
        <button type="button" id="prevBtn">Previous</button>
        <button type="button" id="nextBtn">Next</button>
      </div>

    </form>
  </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;
}

.form-container {
  background: #fff;
  width: 360px;
  padding: 25px;
  border-radius: 12px;
  box-shadow: 0 20px 40px rgba(0,0,0,0.15);
}

h2 {
  text-align: center;
  margin-bottom: 20px;
}

.progress-bar {
  width: 100%;
  height: 6px;
  background: #e5e7eb;
  border-radius: 10px;
  margin-bottom: 25px;
}

.progress {
  height: 100%;
  width: 0%;
  background: #4f46e5;
  border-radius: 10px;
  transition: width 0.3s ease;
}

.step {
  display: none;
}

.step.active {
  display: block;
}

label {
  display: block;
  margin-bottom: 5px;
  font-size: 14px;
}

input {
  width: 100%;
  padding: 10px;
  border-radius: 6px;
  border: 1px solid #ccc;
  margin-bottom: 20px;
}

.buttons {
  display: flex;
  justify-content: space-between;
}

button {
  padding: 10px 20px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
}

#prevBtn {
  background: #042453;
  color: white;
}

#nextBtn {
  background: #042453;
  color: white;
}

button:hover {
  opacity: 0.9;
}

Javascript Code

const steps = document.querySelectorAll(".step");
const nextBtn = document.getElementById("nextBtn");
const prevBtn = document.getElementById("prevBtn");
const progress = document.getElementById("progress");

let currentStep = 0;

updateForm();

nextBtn.addEventListener("click", () => {
  if (!validateStep()) return;

  currentStep++;

  if (currentStep >= steps.length) {
    alert("Form submitted successfully ✅");
    currentStep = steps.length - 1;
  }

  updateForm();
});

prevBtn.addEventListener("click", () => {
  currentStep--;
  updateForm();
});

function updateForm() {
  steps.forEach((step, index) => {
    step.classList.toggle("active", index === currentStep);
  });

  prevBtn.style.display = currentStep === 0 ? "none" : "inline-block";

  nextBtn.innerText =
    currentStep === steps.length - 1 ? "Submit" : "Next";

  progress.style.width =
    ((currentStep + 1) / steps.length) * 100 + "%";
}

function validateStep() {
  const input = steps[currentStep].querySelector("input");

  if (input.value.trim() === "") {
    alert("Please fill the field before continuing ❌");
    return false;
  }
  return true;
}
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Related Projects

Day 5 : Pagination Component

A reusable pagination UI with page navigation and active state handling.

Concepts: DOM manipulation, event handling, conditional rendering.

Day 6 : Accordion / FAQ

Expandable FAQ component with smooth animations and single-item toggle behavior.

Concepts: DOM manipulation, event handling, UI state management

Day 7 : Tabs Navigation System

Switches content dynamically using a tab-based navigation UI.

Concepts: DOM manipulation, event handling, UI state management.