Multi-Step Form

Wizard form pattern using <ol class="steps"> for progress and semantic <section> elements for each step. Native HTML — no framework needed.

Live Example

  1. 1 Account
  2. 2 Profile
  3. 3 Confirm

Account Details

<!-- Progress indicator -->
<ol class="steps" role="list" aria-label="Form steps">
  <li data-active="true"><i>1</i> <span>Account</span></li>
  <li><i>2</i> <span>Profile</span></li>
  <li><i>3</i> <span>Confirm</span></li>
</ol>

<!-- Each step is a semantic section -->
<form novalidate>
  <section id="step1" aria-label="Account details">
    <h3>Account Details</h3>
    <label for="email">Email</label>
    <input type="email" id="email" required>
  </section>

  <section id="step2" aria-label="Profile" hidden>
    ...
  </section>

  <nav aria-label="Step navigation">
    <button type="button" class="secondary" id="prev">← Previous</button>
    <button type="button" class="primary" id="next">Next →</button>
  </nav>
</form>

Step Navigation JavaScript

const steps = document.querySelectorAll('#msf-steps li');
const sections = document.querySelectorAll('#msf-form section');
let current = 0;

function goTo(n) {
  // Hide all, show target
  sections.forEach((s, i) => s.hidden = i !== n);
  // Update step indicators
  steps.forEach((s, i) => {
    s.removeAttribute('data-active');
    s.removeAttribute('data-completed');
    if (i < n) s.dataset.completed = 'true';
    if (i === n) s.dataset.active = 'true';
  });
  current = n;
  // Show/hide prev/next/submit
  document.getElementById('msf-prev').disabled = n === 0;
  document.getElementById('msf-next').hidden = n === steps.length - 1;
  document.getElementById('msf-submit').hidden = n !== steps.length - 1;
}

document.getElementById('msf-next').addEventListener('click', () => goTo(current + 1));
document.getElementById('msf-prev').addEventListener('click', () => goTo(current - 1));

Semantic Structure

ElementRole
ol.stepsVisual progress — data-active and data-completed drive appearance
form sectionEach wizard step — toggled with hidden attribute
navPrevious/Next/Submit buttons — scoped to form navigation
section[aria-label]Announces current step context to screen readers

Accessibility

  • Each step section has aria-label describing its purpose
  • Use aria-live="polite" to announce step changes
  • Focus the first input when advancing to a new step
  • Validate each step before allowing forward navigation
  • Progress indicator must be perceivable without colour — numbers + labels

Features

  • Semantic Structure - Built with native HTML5 elements for maximum reliability.
  • Theme Aware - Automatically adapts to all 22 Axiom01 themes via OKLCH tokens.
  • Fully Responsive - Scales perfectly from mobile to desktop screens.
  • No JS Dependency - Core functionality relies on pure CSS for maximum performance.
  • Customizable - Easily extendable via Axiom01's design tokens and modifiers.

Use Cases

The Multi Step Form component is designed for versatile implementation across modern web applications. Ideal scenarios include:

  • Dashboards & Admin Panels - Structured data presentation and interface control.
  • Content Management Systems - Organizing complex information hierarchies and media.
  • E-Commerce Platforms - Enhancing product discovery and user workflows.
  • Marketing Sites - Highlighting key product offerings cleanly and effectively.
  • SaaS Applications - Delivering native-feeling, responsive app experiences.