Snippets Form

Bootstrap 5 Multi-Step Registration Form with Validation

A three-step registration wizard with inline validation, a password strength meter and a review step before submitting.

Bootstrap 5 No jQuery Nov 2020 1.9K views

<section class="wdw-stage">
  <div class="container" style="max-width:980px">
    <div class="wdw-card overflow-hidden" id="regWiz">
      <div class="row g-0">
        <aside class="col-md-5 wdw-aurora text-white p-4 p-md-5 d-flex flex-column justify-content-center">
          <span class="wdw-eyebrow text-white-50">Create your account</span>
          <h2 class="wdw-heading h3 text-white mt-1 mb-3">Everything you need, in one place</h2>
          <ul class="list-unstyled d-grid gap-3 mb-0 small">
            <li class="d-flex gap-2"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12l5 5L20 7"/></svg>Free forever for personal projects</li>
            <li class="d-flex gap-2"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12l5 5L20 7"/></svg>Sync across all your devices</li>
            <li class="d-flex gap-2"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12l5 5L20 7"/></svg>No credit card, cancel any time</li>
          </ul>
        </aside>
        <div class="col-md-7 p-4 p-md-5">
          <ol class="wz-steps list-unstyled d-flex align-items-center mb-4" aria-label="Registration progress">
            <li class="wz-step" data-ind><span class="wz-dot" aria-hidden="true">1</span><span class="visually-hidden">Step 1</span></li>
            <li class="wz-line" aria-hidden="true"></li>
            <li class="wz-step" data-ind><span class="wz-dot" aria-hidden="true">2</span><span class="visually-hidden">Step 2</span></li>
            <li class="wz-line" aria-hidden="true"></li>
            <li class="wz-step" data-ind><span class="wz-dot" aria-hidden="true">3</span><span class="visually-hidden">Step 3</span></li>
          </ol>
          <span class="wdw-eyebrow">Step <span data-step-now>1</span> of 3</span>
          <h1 class="wdw-heading h3 mt-1 mb-4" data-step-title tabindex="-1">Your details</h1>
      <form novalidate>
        <div data-pane="0">
          <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 autocomplete="given-name"><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 autocomplete="family-name"><label for="wzLast">Last name</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="Birthday" required max="2012-12-31" autocomplete="bday"><label for="wzBirth">Birthday</label><div class="invalid-feedback">Enter a valid date.</div></div></div>
            <div class="col-12">
              <fieldset><legend class="form-label small fw-semibold">Gender</legend>
              <div class="btn-group w-100" role="group">
                <input type="radio" class="btn-check" name="wzGender" id="wzF" checked><label class="btn btn-outline-primary rounded-start-pill" for="wzF">Female</label>
                <input type="radio" class="btn-check" name="wzGender" id="wzM"><label class="btn btn-outline-primary" for="wzM">Male</label>
                <input type="radio" class="btn-check" name="wzGender" id="wzO"><label class="btn btn-outline-primary rounded-end-pill" for="wzO">Prefer not to say</label>
              </div></fieldset>
            </div>
          </div>
        </div>

        <div data-pane="1" hidden>
          <div class="form-floating mb-3"><input type="email" class="form-control" id="wzEmail" placeholder="Email" required autocomplete="email"><label for="wzEmail">Email address</label><div class="invalid-feedback">Enter a valid email address.</div></div>
          <div class="form-floating mb-2"><input type="password" class="form-control" id="wzPass" placeholder="Password" required minlength="8" autocomplete="new-password"><label for="wzPass">Password</label><div class="invalid-feedback">Use at least 8 characters.</div></div>
          <div class="d-flex align-items-center gap-2 mb-3" aria-live="polite">
            <div class="progress flex-grow-1" style="height:4px"><div class="progress-bar" data-meter style="width:0"></div></div>
            <small class="text-body-secondary" data-meter-label style="min-width:3.5rem"> </small>
          </div>
          <div class="form-floating"><input type="password" class="form-control" id="wzPass2" placeholder="Confirm" required autocomplete="new-password"><label for="wzPass2">Confirm password</label><div class="invalid-feedback">Passwords do not match.</div></div>
        </div>

        <div data-pane="2" hidden>
          <dl class="bg-body-tertiary rounded-4 p-3 mb-3 small">
            <div class="d-flex justify-content-between py-1"><dt class="fw-normal text-body-secondary">Name</dt><dd class="mb-0 fw-semibold" data-sum="name"></dd></div>
            <div class="d-flex justify-content-between py-1"><dt class="fw-normal text-body-secondary">Birthday</dt><dd class="mb-0 fw-semibold" data-sum="birth"></dd></div>
            <div class="d-flex justify-content-between py-1"><dt class="fw-normal text-body-secondary">Email</dt><dd class="mb-0 fw-semibold" data-sum="email"></dd></div>
          </dl>
          <div class="form-check mb-2"><input class="form-check-input" type="checkbox" id="wzTerms" required><label class="form-check-label" for="wzTerms">I accept the <a href="#" class="link-primary">terms of service</a></label><div class="invalid-feedback">You must accept to continue.</div></div>
          <div class="form-check"><input class="form-check-input" type="checkbox" id="wzNews"><label class="form-check-label" for="wzNews">Send me product updates</label></div>
        </div>

        <div class="alert alert-success d-flex gap-2 align-items-center mt-3 mb-0" role="status" data-done hidden>Account created. Welcome aboard! (Demo only)</div>

        <div class="d-flex gap-2 mt-4" data-nav>
          <button type="button" class="btn btn-outline-secondary rounded-pill px-4" data-back hidden>Back</button>
          <button type="button" class="btn btn-primary rounded-pill flex-grow-1" data-next>Continue</button>
        </div>
      </form>
        </div>
      </div>
    </div>
  </div>
</section>

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