Snippets Form Wizard

Bootstrap 5 Multi-Step Form Wizard with Validation

A three-step form wizard with a progress stepper that fills as you go, website-type option cards, per-step validation and a recap on the confirmation screen.

Bootstrap 5 No jQuery Jun 2020 2.6K views

<section class="wdw-stage">
  <div class="container" style="max-width: 860px">
    <ol class="fw-steps list-unstyled d-flex mb-4" aria-label="Progress">
      <li class="fw-step is-current" data-step="1"><span class="fw-dot">1</span><span class="fw-label">Build</span></li>
      <li class="fw-step" data-step="2"><span class="fw-dot">2</span><span class="fw-label">Design</span></li>
      <li class="fw-step" data-step="3"><span class="fw-dot">3</span><span class="fw-label">Confirm</span></li>
    </ol>
    <p class="visually-hidden" role="status" id="fw-status">Step 1 of 3</p>

    <form class="wdw-card p-4 p-md-5 py-md-5 fw-form" novalidate>
      <div class="fw-pane" data-pane="1">
        <span class="wdw-eyebrow">Step 1 of 3</span>
        <h2 class="wdw-heading display-6 fs-1 mb-2" tabindex="-1">Who are you building for?</h2>
        <p class="wdw-muted fs-5 mb-4">Tell us your name and where to send the estimate.</p>
        <div class="row g-3">
          <div class="col-md-6">
            <div class="form-floating">
              <input type="text" class="form-control" id="fw-name" placeholder="Name" autocomplete="name" required>
              <label for="fw-name">Name</label>
              <div class="invalid-feedback">Please enter a name.</div>
            </div>
          </div>
          <div class="col-md-6">
            <div class="form-floating">
              <input type="email" class="form-control" id="fw-email" placeholder="Email" autocomplete="email" required>
              <label for="fw-email">Email</label>
              <div class="invalid-feedback">Please enter a valid email.</div>
            </div>
          </div>
        </div>
      </div>

      <div class="fw-pane" data-pane="2" hidden>
        <span class="wdw-eyebrow">Step 2 of 3</span>
        <h2 class="wdw-heading display-6 fs-1 mb-2" tabindex="-1">Describe the website</h2>
        <p class="wdw-muted mb-4">Pick a type, then give it a title and a short brief.</p>
        <fieldset class="mb-3">
          <legend class="visually-hidden">Website type</legend>
          <div class="row g-3">
            <div class="col-4">
              <input type="radio" class="btn-check" name="fw-type" id="fw-t1" value="Portfolio" checked>
              <label class="btn fw-type w-100" for="fw-t1">
                <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="3"/><path d="M3 15l5-5 5 5 3-3 5 5"/></svg>Portfolio</label>
            </div>
            <div class="col-4">
              <input type="radio" class="btn-check" name="fw-type" id="fw-t2" value="Online shop">
              <label class="btn fw-type w-100" for="fw-t2">
                <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 8h14l-1 12H6zM9 8a3 3 0 0 1 6 0"/></svg>Online shop</label>
            </div>
            <div class="col-4">
              <input type="radio" class="btn-check" name="fw-type" id="fw-t3" value="Blog">
              <label class="btn fw-type w-100" for="fw-t3">
                <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 4h14v16H5zM8 9h8M8 13h8M8 17h5"/></svg>Blog</label>
            </div>
          </div>
        </fieldset>
        <div class="form-floating mb-3">
          <input type="text" class="form-control" id="fw-title" placeholder="Website title" required>
          <label for="fw-title">Website title</label>
          <div class="invalid-feedback">Please enter a title.</div>
        </div>
        <div class="form-floating">
          <textarea class="form-control" id="fw-desc" placeholder="Description" style="height: 8rem" required></textarea>
          <label for="fw-desc">Short description</label>
          <div class="invalid-feedback">Please add a short description.</div>
        </div>
      </div>

      <div class="fw-pane" data-pane="3" hidden>
        <div class="d-flex align-items-center gap-3 mb-4">
          <span class="wdw-icon rounded-circle text-success" style="width:3.5rem;height:3.5rem;background:var(--bs-success-bg-subtle)" aria-hidden="true">
            <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg>
          </span>
          <div>
            <h2 class="wdw-heading display-6 fs-2 mb-0" tabindex="-1">Thank you!</h2>
            <p class="wdw-muted mb-0">An estimate will be sent to <strong class="text-body-emphasis" id="fw-sent">your inbox</strong>.</p>
          </div>
        </div>
        <dl class="row g-0 mb-0 rounded-3 bg-body-tertiary p-3">
          <dt class="col-sm-4 wdw-muted fw-semibold">Name</dt><dd class="col-sm-8 mb-2" id="fw-r-name"></dd>
          <dt class="col-sm-4 wdw-muted fw-semibold">Email</dt><dd class="col-sm-8 mb-2" id="fw-r-email"></dd>
          <dt class="col-sm-4 wdw-muted fw-semibold">Type</dt><dd class="col-sm-8 mb-2" id="fw-r-type"></dd>
          <dt class="col-sm-4 wdw-muted fw-semibold">Title</dt><dd class="col-sm-8 mb-0" id="fw-r-title"></dd>
        </dl>
      </div>

      <div class="d-flex justify-content-between align-items-center mt-4 fw-actions">
        <button type="button" class="btn btn-outline-secondary rounded-pill px-4 fw-back">Back</button>
        <button type="submit" class="btn btn-primary rounded-pill px-4 fw-next">Next
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></button>
      </div>
    </form>
  </div>
</section>

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