About this snippet

Guide users through complex data entry with this modern multi-step form. It features a clear progress stepper at the top and smooth transitions between sections, which improves completion rates by breaking long forms into manageable chunks.

Size
6.0 KB
Uses
HTML, CSS, JavaScript
Loads
Nothing external
Views
555
<div class="form-container">
  <div class="stepper-wrapper">
    <div class="step active">
      <div class="circle">1</div>
      <div class="label">Account</div>
    </div>
    <div class="line"></div>
    <div class="step">
      <div class="circle">2</div>
      <div class="label">Personal</div>
    </div>
    <div class="line"></div>
    <div class="step">
      <div class="circle">3</div>
      <div class="label">Finish</div>
    </div>
  </div>

  <form id="multiStepForm">
    <!-- Step 1 -->
    <div class="form-step active">
      <h2>Account Information</h2>
      <div class="input-group">
        <label>Username</label>
        <input type="text" placeholder="Enter username" required>
      </div>
      <div class="input-group">
        <label>Password</label>
        <input type="password" placeholder="Enter password" required>
      </div>
      <div class="btn-group">
        <button type="button" class="btn-next">Next</button>
      </div>
    </div>

    <!-- Step 2 -->
    <div class="form-step">
      <h2>Personal Details</h2>
      <div class="input-group">
        <label>Full Name</label>
        <input type="text" placeholder="John Doe" required>
      </div>
      <div class="input-group">
        <label>Email Address</label>
        <input type="email" placeholder="john@example.com" required>
      </div>
      <div class="btn-group">
        <button type="button" class="btn-prev">Back</button>
        <button type="button" class="btn-next">Next</button>
      </div>
    </div>

    <!-- Step 3 -->
    <div class="form-step">
      <h2>Confirmation</h2>
      <p>Please review your details before submitting.</p>
      <div class="summary">
        <p>Your account is ready to be created. Click submit to finish the process.</p>
      </div>
      <div class="btn-group">
        <button type="button" class="btn-prev">Back</button>
        <button type="submit" class="btn-submit">Submit</button>
      </div>
    </div>
  </form>
</div>
.form-container {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  background: #ffffff;
  padding: 40px;
  border-radius: 16px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.05);
  max-width: 500px;
  margin: 0 auto;
  width: 100%;
}
.stepper-wrapper {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 40px;
  position: relative;
}
.step {
  display: flex;
  flex-direction: column;
  align-items: center;
  z-index: 2;
  position: relative;
}
.circle {
  width: 35px;
  height: 35px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid #e5e7eb;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  color: #9ca3af;
  transition: all 0.3s ease;
}
.label {
  margin-top: 8px;
  font-size: 0.8rem;
  color: #9ca3af;
  font-weight: 500;
}
.line {
  flex: 1;
  height: 2px;
  background: #e5e7eb;
  margin: 0 -10px 25px -10px;
  z-index: 1;
  transition: background 0.3s ease;
}
/* Active & Completed States */
.step.active .circle {
  border-color: #3b82f6;
  color: #3b82f6;
}
.step.active .label {
  color: #3b82f6;
}
.step.completed .circle {
  background: #3b82f6;
  border-color: #3b82f6;
  color: white;
}
.line.completed {
  background: #3b82f6;
}

.form-step {
  display: none;
  animation: fade 0.3s ease-in-out;
}
.form-step.active {
  display: block;
}
@keyframes fade {
  from { opacity: 0; transform: translateY(5px); }
  to { opacity: 1; transform: translateY(0); }
}
.form-step h2 {
  margin: 0 0 20px 0;
  color: #1f2937;
  font-size: 1.5rem;
}
.input-group {
  margin-bottom: 20px;
}
.input-group label {
  display: block;
  margin-bottom: 8px;
  font-weight: 500;
  color: #4b5563;
}
.input-group input {
  width: 100%;
  padding: 12px;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  font-size: 1rem;
  outline: none;
  box-sizing: border-box;
}
.input-group input:focus {
  border-color: #3b82f6;
}
.btn-group {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 30px;
}
button {
  padding: 12px 24px;
  border: none;
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s;
}
.btn-next, .btn-submit {
  background: #3b82f6;
  color: white;
}
.btn-next:hover, .btn-submit:hover {
  background: #2563eb;
}
.btn-prev {
  background: #f3f4f6;
  color: #374151;
}
.btn-prev:hover {
  background: #e5e7eb;
}
const nextBtns = document.querySelectorAll(".btn-next");
const prevBtns = document.querySelectorAll(".btn-prev");
const steps = document.querySelectorAll(".step");
const formSteps = document.querySelectorAll(".form-step");
const lines = document.querySelectorAll(".line");

let currentStep = 0;

nextBtns.forEach((btn) => {
  btn.addEventListener("click", () => {
    // Simple validation (check required fields)
    const inputs = formSteps[currentStep].querySelectorAll("input[required]");
    let valid = true;
    inputs.forEach(input => {
        if(!input.value) {
            valid = false;
            input.style.borderColor = "red";
        } else {
            input.style.borderColor = "#d1d5db";
        }
    });
    
    if (valid) {
        currentStep++;
        updateForm();
    }
  });
});

prevBtns.forEach((btn) => {
  btn.addEventListener("click", () => {
    currentStep--;
    updateForm();
  });
});

function updateForm() {
  // Update Form Steps
  formSteps.forEach((step) => step.classList.remove("active"));
  formSteps[currentStep].classList.add("active");

  // Update Stepper UI
  steps.forEach((step, idx) => {
    if (idx <= currentStep) {
        step.classList.add("active");
    } else {
        step.classList.remove("active");
    }
    
    // Mark previous steps as completed
    if (idx < currentStep) {
        step.classList.add("completed");
    } else {
        step.classList.remove("completed");
    }
  });
  
  // Update Connecting Lines
  lines.forEach((line, idx) => {
      if(idx < currentStep) {
          line.classList.add("completed");
      } else {
          line.classList.remove("completed");
      }
  });
}
Esc
↑↓ moveEnter select

Start from a template

Open an .html file, or HTML, CSS, JS, Markdown, Less or TypeScript files. You can also drop them here. Styles and scripts go into their panes.

Share

Source

Keyboard shortcuts

Save