Snippets Form Wizard

Bootstrap 5 Multi-Step Signup Form Wizard

A four-step signup wizard with a progress tracker, floating-label fields, per-step validation and a success screen.

Bootstrap 5 No jQuery May 2020 2.8K views

<section class="wdw-stage">
  <div class="container" style="max-width:640px">
    <div class="wdw-card p-4 p-md-5">
      <div class="text-center mb-4">
        <span class="wdw-eyebrow">Create account</span>
        <h2 class="wdw-heading h2 mt-1 mb-1">Sign up in four steps</h2>
        <p class="wdw-muted mb-0" id="wzHint">Step 1 of 4: Account</p>
      </div>

      <ol class="wz-steps list-unstyled d-flex justify-content-between mb-4" id="wzSteps" aria-label="Progress">
        <li class="wz-step is-current"><span class="wz-dot">1</span><span class="wz-label">Account</span></li>
        <li class="wz-step"><span class="wz-dot">2</span><span class="wz-label">Personal</span></li>
        <li class="wz-step"><span class="wz-dot">3</span><span class="wz-label">Payment</span></li>
        <li class="wz-step"><span class="wz-dot">4</span><span class="wz-label">Finish</span></li>
      </ol>

      <form id="wzForm" novalidate>
        <fieldset class="wz-pane" data-step="1">
          <legend class="visually-hidden">Account details</legend>
          <div class="form-floating mb-3"><input type="email" class="form-control" id="wzEmail" placeholder="Email" required><label for="wzEmail">Email address</label><div class="invalid-feedback">Enter a valid email.</div></div>
          <div class="form-floating mb-3"><input type="text" class="form-control" id="wzUser" placeholder="Username" required minlength="3"><label for="wzUser">Username</label><div class="invalid-feedback">At least 3 characters.</div></div>
          <div class="row g-3">
            <div class="col-sm-6"><div class="form-floating"><input type="password" class="form-control" id="wzPass" placeholder="Password" required minlength="6"><label for="wzPass">Password</label><div class="invalid-feedback">At least 6 characters.</div></div></div>
            <div class="col-sm-6"><div class="form-floating"><input type="password" class="form-control" id="wzPass2" placeholder="Confirm" required><label for="wzPass2">Confirm password</label><div class="invalid-feedback">Passwords must match.</div></div></div>
          </div>
        </fieldset>

        <fieldset class="wz-pane" data-step="2" hidden>
          <legend class="visually-hidden">Personal details</legend>
          <div class="row g-3">
            <div class="col-sm-6"><div class="form-floating"><input type="text" class="form-control" id="wzFirst" placeholder="First" required><label for="wzFirst">First name</label><div class="invalid-feedback">Required.</div></div></div>
            <div class="col-sm-6"><div class="form-floating"><input type="text" class="form-control" id="wzLast" placeholder="Last" required><label for="wzLast">Last name</label><div class="invalid-feedback">Required.</div></div></div>
            <div class="col-12"><div class="form-floating"><input type="tel" class="form-control" id="wzPhone" placeholder="Phone" required><label for="wzPhone">Phone number</label><div class="invalid-feedback">Required.</div></div></div>
            <div class="col-12"><div class="form-floating"><input type="date" class="form-control" id="wzBirth" placeholder="Birth" required><label for="wzBirth">Date of birth</label><div class="invalid-feedback">Required.</div></div></div>
          </div>
        </fieldset>

        <fieldset class="wz-pane" data-step="3" hidden>
          <legend class="visually-hidden">Payment details</legend>
          <div class="form-floating mb-3"><input type="text" class="form-control" id="wzCard" inputmode="numeric" placeholder="Card" required pattern="[0-9 ]{13,19}"><label for="wzCard">Card number</label><div class="invalid-feedback">Enter a valid card number.</div></div>
          <div class="form-floating mb-3"><input type="text" class="form-control" id="wzHolder" placeholder="Name" required><label for="wzHolder">Name on card</label><div class="invalid-feedback">Required.</div></div>
          <div class="row g-3">
            <div class="col-6"><div class="form-floating"><input type="text" class="form-control" id="wzExp" placeholder="MM/YY" required pattern="[0-9]{2}/[0-9]{2}"><label for="wzExp">Expiry (MM/YY)</label><div class="invalid-feedback">Use MM/YY.</div></div></div>
            <div class="col-6"><div class="form-floating"><input type="text" class="form-control" id="wzCvc" inputmode="numeric" placeholder="CVC" required pattern="[0-9]{3,4}"><label for="wzCvc">CVC</label><div class="invalid-feedback">3 or 4 digits.</div></div></div>
          </div>
        </fieldset>

        <div class="wz-pane text-center py-4" data-step="4" hidden>
          <span class="wz-done mx-auto mb-3"><svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg></span>
          <h3 class="h4 fw-bold">You're all set</h3>
          <p class="wdw-muted mb-0">Your account is ready. We've sent a confirmation to your inbox.</p>
        </div>

        <div class="d-flex justify-content-between gap-2 mt-4" id="wzNav">
          <button type="button" class="btn btn-outline-secondary rounded-pill px-4" id="wzBack" disabled>Back</button>
          <button type="button" class="btn btn-primary rounded-pill px-4" id="wzNext">Next step</button>
        </div>
      </form>
    </div>
  </div>
</section>

Built on Bootstrap 5.3.8 with plain JavaScript — no jQuery. Supports light and dark mode via data-bs-theme.

Free to use in personal and commercial projects under the MIT license.