Snippets Animation

Bootstrap 5 Multi-Step Form Wizard with Progress Bar

A four-step sign-up wizard with a numbered stepper, an animated progress bar, per-step validation and a success screen.

Bootstrap 5 No jQuery Jun 2020 2.7K views

<section class="wdw-stage">
  <div class="container" style="max-width: 640px;">
    <div class="wdw-card overflow-hidden">
      <div class="wdw-aurora wz-band px-4 py-4 text-center">
        <span class="wdw-eyebrow text-white-50">Sign up</span>
        <h1 class="h3 wdw-heading mt-1 mb-1 text-white">Create your account</h1>
        <p class="mb-0 text-white-50">Complete each step to get started.</p>
      </div>
      <div class="p-4 p-md-5">
      <ol class="wz-steps list-unstyled d-flex mb-3" id="wzSteps" aria-hidden="true">
        <li class="wz-step active" aria-current="step"><span class="wz-dot">1</span><span class="wz-name">Account</span></li>
        <li class="wz-step"><span class="wz-dot">2</span><span class="wz-name">Personal</span></li>
        <li class="wz-step"><span class="wz-dot">3</span><span class="wz-name">Photo</span></li>
        <li class="wz-step"><span class="wz-dot">4</span><span class="wz-name">Finish</span></li>
      </ol>
      <div class="progress wz-progress mb-4" role="progressbar" aria-label="Form completion" aria-valuemin="0" aria-valuemax="100" aria-valuenow="25" id="wzProgress">
        <div class="progress-bar" style="width:25%"></div>
      </div>
      <form id="wzForm" novalidate>
        <fieldset class="wz-pane" data-step="1">
          <legend tabindex="-1" class="h5 fw-bold mb-3 d-flex justify-content-between align-items-baseline">Account information <small class="wdw-muted fw-normal">Step 1 of 4</small></legend>
          <div class="d-grid gap-3">
            <div class="form-floating"><input type="email" class="form-control" id="wzEmail" placeholder="Email" required><label for="wzEmail">Email</label><div class="invalid-feedback">Enter a valid email.</div></div>
            <div class="form-floating"><input type="text" class="form-control" id="wzUser" placeholder="Username" required><label for="wzUser">Username</label><div class="invalid-feedback">Choose a username.</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" minlength="8" required><label for="wzPass">Password</label><div class="invalid-feedback">Min. 8 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>
          </div>
        </fieldset>
        <fieldset class="wz-pane" data-step="2" hidden>
          <legend tabindex="-1" class="h5 fw-bold mb-3 d-flex justify-content-between align-items-baseline">Personal information <small class="wdw-muted fw-normal">Step 2 of 4</small></legend>
          <div class="d-grid gap-3">
            <div class="row g-3">
              <div class="col-sm-6"><div class="form-floating"><input type="text" class="form-control" id="wzFirst" placeholder="First name" 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 name" required><label for="wzLast">Last name</label><div class="invalid-feedback">Required.</div></div></div>
            </div>
            <div class="form-floating"><input type="tel" class="form-control" id="wzPhone" placeholder="Contact number" required><label for="wzPhone">Contact number</label><div class="invalid-feedback">Required.</div></div>
            <div class="form-floating"><input type="tel" class="form-control" id="wzPhone2" placeholder="Alternate number"><label for="wzPhone2">Alternate number (optional)</label></div>
          </div>
        </fieldset>
        <fieldset class="wz-pane" data-step="3" hidden>
          <legend tabindex="-1" class="h5 fw-bold mb-3 d-flex justify-content-between align-items-baseline">Upload images <small class="wdw-muted fw-normal">Step 3 of 4</small></legend>
          <div class="d-grid gap-3">
            <label class="wz-drop" for="wzPhoto"><span class="wdw-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 16V4M7 9l5-5 5 5M4 20h16"/></svg></span><span class="fw-semibold">Your photo</span><span class="small wdw-muted wz-fname" data-empty="Drop an image or click to browse">Drop an image or click to browse</span><input type="file" class="visually-hidden" id="wzPhoto" accept="image/*"></label>
            <label class="wz-drop" for="wzSign"><span class="wdw-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 16V4M7 9l5-5 5 5M4 20h16"/></svg></span><span class="fw-semibold">Signature</span><span class="small wdw-muted wz-fname" data-empty="Drop an image or click to browse">Drop an image or click to browse</span><input type="file" class="visually-hidden" id="wzSign" accept="image/*"></label>
          </div>
        </fieldset>
        <fieldset class="wz-pane text-center py-3" data-step="4" hidden>
          <legend class="visually-hidden">Finish</legend>
          <span class="wz-check mb-3"><svg width="34" height="34" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg></span>
          <h2 class="h4 wdw-heading">You are all set</h2>
          <p class="wdw-muted mb-0">Your account has been created. Check your inbox to confirm your email.</p>
        </fieldset>
        <div class="d-flex justify-content-between gap-2 mt-4" id="wzActions">
          <button type="button" class="btn btn-outline-primary rounded-pill px-4" id="wzPrev" disabled style="visibility:hidden">Previous</button>
          <button type="button" class="btn btn-primary rounded-pill px-4" id="wzNext">Next</button>
        </div>
      </form>
      </div>
    </div>
  </div>
</section>

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