|$ curl https://forge-ai.dev/api/markdown?path=docs/components/steppers
$cat docs/steppers-&-wizards.md
updated Recently·22 min read·published

Steppers & Wizards

CSSHTMLTailwindBootstrapUIIntermediate🎯Free Tools
Introduction

Steppers visualize progress through a multi-step process. This guide covers production-ready patterns in plain HTML/CSS, Tailwind CSS, and Bootstrap \u2014 from simple numbered indicators to interactive wizards, vertical timelines, compact inline steppers, and validation states.

info

Use aria-current="step" on the active step so screen readers announce the current position. Keep step labels short and avoid relying on color alone.
Basic Horizontal Stepper

A numbered step indicator showing completed, active, and upcoming steps connected by lines. Completed steps display a checkmark, the active step is highlighted with a glow, and upcoming steps remain dimmed.

basic-stepper
Live
untitled.html
HTML
1<div class="stepper">
2 <div class="step done">
3 <div class="step-circle">
4 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" width="14" height="14">
5 <polyline points="20 6 9 17 4 12"/>
6 </svg>
7 </div>
8 <span class="step-label">
9 Account
10 </span>
11 </div>
12 <div class="step-line done">
13 </div>
14 <div class="step done">
15 <div class="step-circle">
16 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" width="14" height="14">
17 <polyline points="20 6 9 17 4 12"/>
18 </svg>
19 </div>
20 <span class="step-label">
21 Profile
22 </span>
23 </div>
24 <div class="step-line done">
25 </div>
26 <div class="step active">
27 <div class="step-circle">
28 3
29 </div>
30 <span class="step-label">
31 Billing
32 </span>
33 </div>
34 <div class="step-line">
35 </div>
36 <div class="step">
37 <div class="step-circle">
38 4
39 </div>
40 <span class="step-label">
41 Confirm
42 </span>
43 </div>
44</div>
preview
Interactive Wizard

A fully interactive wizard with back/next navigation. Each step displays different content, and the indicator updates to reflect the current position. The final step changes the Next button to a Finish button.

interactive-wizard
Live
untitled.html
HTML
1<div class="wizard">
2 <div class="w-stepper">
3 <div class="ws done" data-step="0">
4 <span class="ws-n">
5 1
6 </span>
7 <span class="ws-t">
8 Details
9 </span>
10 </div>
11 <div class="ws-line done">
12 </div>
13 <div class="ws active" data-step="1">
14 <span class="ws-n">
15 2
16 </span>
17 <span class="ws-t">
18 Preferences
19 </span>
20 </div>
21 <div class="ws-line">
22 </div>
23 <div class="ws" data-step="2">
24 <span class="ws-n">
25 3
26 </span>
27 <span class="ws-t">
28 Review
29 </span>
30 </div>
31 </div>
32 <div class="w-content" id="w-content">
33 <div class="w-panel active" data-panel="0">
34 <h4>
35 Account Details
36 </h4>
37 <p>
38 Enter your name and email address to create your account.
39 </p>
40 <div class="w-field">
41 <label>
42 Full Name
43 </label>
44 <input type="text" placeholder="Jane Doe" class="w-input"/>
45 </div>
46 <div class="w-field">
47 <label>
48 Email
49 </label>
50 <input type="email" placeholder="jane@example.com" class="w-input"/>
51 </div>
52 </div>
53 <div class="w-panel" data-panel="1">
54 <h4>
55 Preferences
56 </h4>
57 <p>
58 Choose your notification and display preferences.
59 </p>
60 <label class="w-check">
61 <input type="checkbox" checked/>
62 Email notifications
63 </label>
64 <label class="w-check">
65 <input type="checkbox"/>
66 Dark mode
67 </label>
68 <label class="w-check">
69 <input type="checkbox" checked/>
70 Weekly digest
71 </label>
72 </div>
73 <div class="w-panel" data-panel="2">
74 <h4>
75 Review &amp; Confirm
76 </h4>
77 <p>
78 Review your settings before completing setup.
79 </p>
80 <div class="w-summary">
81 <div class="ws-row">
82 <span>
83 Name
84 </span>
85 <span>
86 Jane Doe
87 </span>
88 </div>
89 <div class="ws-row">
90 <span>
91 Email
92 </span>
93 <span>
94 jane@example.com
95 </span>
96 </div>
97 <div class="ws-row">
98 <span>
99 Notifications
100 </span>
101 <span>
102 Enabled
103 </span>
104 </div>
105 </div>
106 </div>
107 </div>
108 <div class="w-actions">
109 <button class="w-btn secondary" id="w-back" disabled>
110 Back
111 </button>
112 <button class="w-btn primary" id="w-next">
113 Next
114 </button>
115 </div>
116</div>
preview
Vertical Stepper

A vertical step layout for sidebars, mobile views, or contexts where horizontal space is limited. Each step shows its content inline below the indicator, connected by a vertical line.

vertical-stepper
Live
untitled.html
HTML
1<div class="v-stepper">
2 <div class="vs done">
3 <div class="vs-indicator">
4 <div class="vs-dot">
5 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" width="12" height="12">
6 <polyline points="20 6 9 17 4 12"/>
7 </svg>
8 </div>
9 <div class="vs-line">
10 </div>
11 </div>
12 <div class="vs-body">
13 <h5>
14 Order Placed
15 </h5>
16 <p>
17 Your order #4829 has been confirmed and is being prepared.
18 </p>
19 <span class="vs-time">
20 2 minutes ago
21 </span>
22 </div>
23 </div>
24 <div class="vs done">
25 <div class="vs-indicator">
26 <div class="vs-dot">
27 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" width="12" height="12">
28 <polyline points="20 6 9 17 4 12"/>
29 </svg>
30 </div>
31 <div class="vs-line">
32 </div>
33 </div>
34 <div class="vs-body">
35 <h5>
36 Processing
37 </h5>
38 <p>
39 Items are being picked and packed at the warehouse.
40 </p>
41 <span class="vs-time">
42 15 minutes ago
43 </span>
44 </div>
45 </div>
46 <div class="vs active">
47 <div class="vs-indicator">
48 <div class="vs-dot">
49 </div>
50 <div class="vs-line">
51 </div>
52 </div>
53 <div class="vs-body">
54 <h5>
55 Shipped
56 </h5>
57 <p>
58 Your package is on its way via FedEx Express.
59 </p>
60 <span class="vs-time">
61 In transit
62 </span>
63 </div>
64 </div>
65 <div class="vs">
66 <div class="vs-indicator">
67 <div class="vs-dot">
68 </div>
69 </div>
70 <div class="vs-body">
71 <h5>
72 Delivered
73 </h5>
74 <p>
75 Estimated arrival: tomorrow by 6 PM.
76 </p>
77 <span class="vs-time">
78 Pending
79 </span>
80 </div>
81 </div>
82</div>
preview
Labeled Steps with Icons

Steps with icons, labels, and sub-labels for richer context. Useful for checkout flows and onboarding where each step has a clear title and description. Uses square icons instead of circles for visual variety.

labeled-steps
Live
untitled.html
HTML
1<div class="labeled-stepper">
2 <div class="ls done">
3 <div class="ls-icon">
4 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16">
5 <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
6 <polyline points="9 22 9 12 15 12 15 22"/>
7 </svg>
8 </div>
9 <div class="ls-info">
10 <span class="ls-title">
11 Address
12 </span>
13 <span class="ls-sub">
14 Shipping info
15 </span>
16 </div>
17 </div>
18 <div class="ls-conn done">
19 </div>
20 <div class="ls done">
21 <div class="ls-icon">
22 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16">
23 <rect x="1" y="4" width="22" height="16" rx="2" ry="2"/>
24 <line x1="1" y1="10" x2="23" y2="10"/>
25 </svg>
26 </div>
27 <div class="ls-info">
28 <span class="ls-title">
29 Payment
30 </span>
31 <span class="ls-sub">
32 Card details
33 </span>
34 </div>
35 </div>
36 <div class="ls-conn">
37 </div>
38 <div class="ls active">
39 <div class="ls-icon">
40 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16">
41 <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/>
42 <polyline points="22 4 12 14.01 9 11.01"/>
43 </svg>
44 </div>
45 <div class="ls-info">
46 <span class="ls-title">
47 Confirm
48 </span>
49 <span class="ls-sub">
50 Review order
51 </span>
52 </div>
53 </div>
54</div>
preview
Minimal Progress Bar

A compact step indicator using a progress bar with step markers \u2014 minimal and space-efficient for toolbars and inline contexts. Shows current step, total steps, and percentage complete.

minimal-progress
Live
untitled.html
HTML
1<div class="mini-progress">
2 <div class="mp-header">
3 <span class="mp-title">
4 Step 2 of 5
5 </span>
6 <span class="mp-pct">
7 40%
8 </span>
9 </div>
10 <div class="mp-track">
11 <div class="mp-fill" style="width:40%">
12 <div class="mp-dot">
13 </div>
14 </div>
15 <div class="mp-markers">
16 <span class="mp-m done">
17 </span>
18 <span class="mp-m done">
19 </span>
20 <span class="mp-m active">
21 </span>
22 <span class="mp-m">
23 </span>
24 <span class="mp-m">
25 </span>
26 </div>
27 </div>
28</div>
preview
Numbered Circles

A simple numbered circle indicator with connecting lines, designed for compact inline use. Each number is always visible (no checkmarks), making it clear which step the user is on. The connecting lines transition color as steps complete.

numbered-circles
Live
untitled.html
HTML
1<div class="nc-demo">
2 <div class="nc-step done">
3 <span>
4 1
5 </span>
6 </div>
7 <div class="nc-line done">
8 </div>
9 <div class="nc-step done">
10 <span>
11 2
12 </span>
13 </div>
14 <div class="nc-line done">
15 </div>
16 <div class="nc-step active">
17 <span>
18 3
19 </span>
20 </div>
21 <div class="nc-line">
22 </div>
23 <div class="nc-step">
24 <span>
25 4
26 </span>
27 </div>
28 <div class="nc-line">
29 </div>
30 <div class="nc-step">
31 <span>
32 5
33 </span>
34 </div>
35</div>
preview
Compact Inline Stepper

A condensed stepper for tight spaces such as form headers, modals, or cards. It replaces labels with tooltips and uses smaller dots while keeping the connection line.

compact-stepper
Live
untitled.html
HTML
1<div class="compact-stepper">
2 <div class="cs done" title="Upload">
3 <span>
4 </span>
5 </div>
6 <div class="cs-line done">
7 </div>
8 <div class="cs done" title="Process">
9 <span>
10 </span>
11 </div>
12 <div class="cs-line">
13 </div>
14 <div class="cs active" title="Verify">
15 <span>
16 </span>
17 </div>
18 <div class="cs-line">
19 </div>
20 <div class="cs" title="Done">
21 <span>
22 </span>
23 </div>
24</div>
preview
Timeline Stepper

A content-rich vertical timeline for audit logs, activity feeds, or multi-phase project tracking. Each entry includes a timestamp, badge, and descriptive text.

timeline-stepper
Live
untitled.html
HTML
1<div class="timeline">
2 <div class="tl done">
3 <div class="tl-badge done">
4 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="12" height="12">
5 <polyline points="20 6 9 17 4 12"/>
6 </svg>
7 </div>
8 <div class="tl-body">
9 <div class="tl-meta">
10 <span class="tl-title">
11 Deployment started
12 </span>
13 <span class="tl-time">
14 10:00 AM
15 </span>
16 </div>
17 <p>
18 Build v2.4.1 triggered from CI pipeline.
19 </p>
20 </div>
21 </div>
22 <div class="tl done">
23 <div class="tl-badge done">
24 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="12" height="12">
25 <polyline points="20 6 9 17 4 12"/>
26 </svg>
27 </div>
28 <div class="tl-body">
29 <div class="tl-meta">
30 <span class="tl-title">
31 Tests passed
32 </span>
33 <span class="tl-time">
34 10:04 AM
35 </span>
36 </div>
37 <p>
38 347 unit tests and 12 integration tests passed.
39 </p>
40 </div>
41 </div>
42 <div class="tl active">
43 <div class="tl-badge active">
44 </div>
45 <div class="tl-body">
46 <div class="tl-meta">
47 <span class="tl-title">
48 Staging deploy
49 </span>
50 <span class="tl-time">
51 10:05 AM
52 </span>
53 </div>
54 <p>
55 Container pushed to staging cluster.
56 </p>
57 </div>
58 </div>
59 <div class="tl">
60 <div class="tl-badge">
61 </div>
62 <div class="tl-body">
63 <div class="tl-meta">
64 <span class="tl-title">
65 Production release
66 </span>
67 <span class="tl-time">
68 Pending
69 </span>
70 </div>
71 <p>
72 Waiting for final approval gate.
73 </p>
74 </div>
75 </div>
76</div>
preview
Error & Warning States

Steps can display error or warning states to indicate validation failures. An error state uses red styling to draw attention, while the step remains clickable for the user to go back and fix the issue.

error-states
Live
untitled.html
HTML
1<div class="err-stepper">
2 <div class="es done">
3 <div class="es-dot done">
4 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" width="12" height="12">
5 <polyline points="20 6 9 17 4 12"/>
6 </svg>
7 </div>
8 <span class="es-label">
9 Personal
10 </span>
11 </div>
12 <div class="es-line done">
13 </div>
14 <div class="es error">
15 <div class="es-dot error">
16 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" width="12" height="12">
17 <line x1="18" y1="6" x2="6" y2="18"/>
18 <line x1="6" y1="6" x2="18" y2="18"/>
19 </svg>
20 </div>
21 <span class="es-label error">
22 Payment
23 </span>
24 </div>
25 <div class="es-line">
26 </div>
27 <div class="es">
28 <div class="es-dot">
29 3
30 </div>
31 <span class="es-label">
32 Confirm
33 </span>
34 </div>
35</div>
preview
CSS Transition Reference

Stepper transitions use CSS transitions on background-color, border-color, and box-shadow. The key is to transition the .done class toggling, which triggers smooth color changes on both the circle and connecting line.

stepper-transitions.css
CSS
1/* Base step circle */
2.step-circle {
3 width: 32px;
4 height: 32px;
5 border-radius: 50%;
6 border: 2px solid #333;
7 background: #0A0A0A;
8 color: #555;
9 transition: all 0.3s ease;
10}
11
12/* Completed state */
13.step.done .step-circle {
14 background: #00FF41;
15 border-color: #00FF41;
16 color: #0A0A0A;
17}
18
19/* Active state with glow */
20.step.active .step-circle {
21 border-color: #00FF41;
22 color: #00FF41;
23 box-shadow: 0 0 12px rgba(0, 255, 65, 0.3);
24}
25
26/* Connecting line */
27.step-line {
28 height: 2px;
29 background: #222;
30 transition: background 0.3s ease;
31}
32
33.step-line.done {
34 background: #00FF41;
35}
HTML Structure

A stepper uses an ordered list of step items, each containing an indicator (circle with number/check), label, and optional content. Connect adjacent steps with a line element and use aria-current="step" on the active step.

stepper-structure.html
HTML
1<ol class="stepper" role="list">
2 <li class="step done" aria-current="false">
3 <div class="step-circle" aria-hidden="true">✓</div>
4 <span class="step-label">Account</span>
5 </li>
6 <li class="step-line" aria-hidden="true"></li>
7 <li class="step active" aria-current="step">
8 <div class="step-circle" aria-hidden="true">2</div>
9 <span class="step-label">Preferences</span>
10 </li>
11 <li class="step-line" aria-hidden="true"></li>
12 <li class="step" aria-current="false">
13 <div class="step-circle" aria-hidden="true">3</div>
14 <span class="step-label">Review</span>
15 </li>
16</ol>
Accessibility

Steppers must communicate progress and state to all users. Do not rely on color alone to indicate completion or errors.

  • Use a real ordered list <ol> with role="list" so screen readers report the total number of steps.
  • Add aria-current="step" to the active step. Mark completed steps with aria-current="false".
  • Provide text alternatives for icon-only checkmarks, such as visually hidden text or aria-label="completed".
  • Announce step changes with an aria-live="polite" region in interactive wizards.
  • Ensure error states include an error message linked via aria-describedby.
  • Respect prefers-reduced-motion by disabling transition animations for users who need reduced motion.

warning

Long step labels break layout on small screens. Keep labels to two words or fewer, and use tooltips or progressive disclosure for additional context.
Best Practices

info

Use aria-current="step" on the active step element so screen readers announce the current position. Mark completed steps with aria-current="false".

warning

Avoid step labels longer than two words. Long labels break the visual rhythm and create layout shifts on smaller screens. Use tooltips for additional context.

best practice

Allow users to click on completed steps to go back and edit previous entries. Never trap users in a wizard \u2014 back navigation should always be available.
  • Keep total step count under 7 \u2014 Miller's Law. For longer processes, group related steps into phases or sub-wizards.
  • Show estimated time remaining alongside step count for long wizards (e.g., "Step 2 of 5 \u00b7 ~3 min left").
  • Validate each step before allowing progression. Highlight errors inline rather than blocking the entire step.
  • Use the prefers-reduced-motion query to disable step transition animations for sensitive users.
  • On mobile, convert horizontal steppers to vertical \u2014 horizontal layouts with 4+ steps overflow on small screens.

Community

Get help on Slack, Discord or VIP

Stuck on a guide? Join the community and ask.