Steps
Step indicators show progress through a multi-step process. Built with CSS counters for auto-numbering, auto-generated connectors, and ARIA attributes for accessibility.
Overview
Step indicators communicate progress through a multi-step process like checkout, registration, or onboarding. The nav.steps pattern uses CSS-only numbered circles, auto-generated connectors, and semantic HTML.
Key features:
- CSS counters for auto-numbering — no manual
<span>1</span>needed - Auto connectors between steps via
::afterpseudo-elements - Checkmark on completed steps (replaces counter number)
- ARIA support —
aria-current="step"for active,aria-labelfor the nav - Variants — labels below, vertical, small/large sizes
- Dark mode — automatic via VB color tokens
- Wizard integration — auto-syncs with
wizard.jswhen present
Basic Step Indicator
The default horizontal layout with numbered circles, labels beside each circle, and auto-generated connectors between steps. Uses <ol> for semantic ordered progression.
Interactive Steps
Completed steps can contain <a> links to allow users to navigate back to earlier steps. Future steps remain plain text (non-clickable). The interactive demo below lets you navigate between steps with Previous/Next buttons.
Labels Below
Use data-labels="below" to position labels below their circles. Connectors run between circles at circle height using absolute positioning. This variant works well for steps with longer labels.
Vertical Steps
Use data-direction="vertical" to stack steps vertically with downward connectors. Useful for sidebar navigation or when you have many steps that need more space.
Size Variants
Use data-size="sm" for compact indicators or data-size="lg" for more prominent ones. The default size is 2rem.
Small
Large
With Wizard Forms
When used inside (or referenced by) a form[data-wizard], the wizard.js controller auto-syncs nav.steps state as the user navigates steps. Point the form to the nav using data-wizard-steps="#id", or place the nav.steps inside the form for auto-discovery.
The wizard automatically:
- Sets
data-completedon all steps before the current one - Sets
aria-current="step"on the current step - Clears attributes from future steps
- Hides conditional steps when they don't apply
States
Each step can be in one of three states:
| State | Attribute | Circle | Label |
|---|---|---|---|
| Future (default) | none | Muted border, surface background | Muted text |
| Active | aria-current="step" |
Interactive background, white number | Bold text |
| Completed | data-completed |
Success background, checkmark | Normal text |
Variants
| Variant | Attribute | Behavior |
|---|---|---|
| Labels beside (default) | none | Circle + label in a row, connector stretches between |
| Labels below | data-labels="below" |
Circle on top, label below, connectors between circles |
| Vertical | data-direction="vertical" |
Steps stacked vertically, connector runs downward |
| Small | data-size="sm" |
1.5rem circles, smaller font |
| Large | data-size="lg" |
2.5rem circles, larger font |
CSS Variables
Override the private --_ variables on nav.steps to customize colors and sizes:
| Variable | Default | Purpose |
|---|---|---|
--_step-size |
2rem |
Circle diameter |
--_step-font |
var(--font-size-s) |
Number/checkmark font size |
--_connector-height |
2px |
Connector line thickness |
--_connector-color |
var(--color-border) |
Default connector color |
--_connector-completed |
var(--color-success) |
Completed connector color |
--_active-bg |
var(--color-interactive) |
Active circle background |
--_completed-bg |
var(--color-success) |
Completed circle background |
--_future-bg |
var(--color-surface-raised) |
Future circle background |
Accessibility
aria-current="step"on the active<li>announces the current step to screen readersaria-labelon the<nav>identifies the navigation purpose<ol>conveys ordered sequence to assistive technology- Completed steps with
<a>links are keyboard-navigable - When used with
wizard.js, step changes are announced via a live region - Future steps (no attributes) have muted visual treatment — not interactive, not focusable
Related
Wizard
Multi-step form patterns with wizard.js integration
Breadcrumb
Hierarchical location navigation
Pagination
Page-level navigation patterns
Nav Element
Full nav element documentation with all variants