02UI

Stepper

A stepper shows progress through a short sequence of screens in a fixed order. People see what is done, where they are, and what is still ahead.

Structure and navigationBuild difficulty: Medium<ol>

Also called Step indicator, Wizard steps, Progress steps.

Details

Add the company name and billing address.

Company and address

Use Next and Back, or click a step you already finished. The current step is filled orange. Completed steps show a check.

For designers

A stepper makes a long form feel finite. Stripe Checkout and most onboarding wizards show three or four named steps so people know the end is near. That reduces abandonment on flows that would feel endless as one page.

The cost is rigidity. Every screen must fit the sequence model. If half your settings are independent toggles, a stepper forces artificial order where a flat page or tabs would be faster.

Checkout is the classic fit. Delivery, payment, review. Each step gates the next because you cannot charge a card before you know the address. Onboarding can use the same shape when later questions depend on earlier answers, like team size before plan pricing.

When to use a stepper

Use a stepper when

  • A task splits into roughly 2 to 5 screens that must happen in order
  • People benefit from seeing progress before they commit at the end
  • Earlier steps can be revisited without restarting the whole flow

Reach for something else when

Variants

Horizontal strip with three states: upcoming, current, and completed with a check.

Horizontal. Numbers or checks in a row with connecting lines. Default for checkout and signup.

Completed. Check icon in the circle, label muted or normal, connector filled to show progress.

Current. Filled circle on the active step, stronger label, connectors behind filled and ahead neutral.

How to build a stepper

Use an ordered list for the steps and mark the active one with aria-current="step".

<ol aria-label="Checkout">
  <li>
    <button type="button" aria-current="step">Delivery</button>
  </li>
  <li>
    <button type="button" disabled>Payment</button>
  </li>
  <li>
    <button type="button" disabled>Review</button>
  </li>
</ol>

Completed steps stay as buttons so people can go back. Disable future steps until validation passes on the current screen. The Next button on the panel should move focus to the first field on the new step, not leave focus on the stepper strip.

Connectors between circles are decorative lines. They should fill with progress colour only up to the last completed step, not colour alone for state (WCAG 1.4.1 pairs with the check or number inside the circle).

Mobile often drops step labels and shows only numbers to save width. If you do that, keep the full label in aria-label on each step button so voice control and screen readers still hear Delivery, not Step 2.

Put the primary action on the step panel, not on the stepper strip. Submit belongs on the review step content, not as a third circle after Review.

Edge cases

Validation failure. Block Next on the current step and point to the invalid field. Do not advance the stepper and show errors on a step the strip no longer marks as current.

Save and resume. If the flow spans sessions, persist step index and field values so the strip matches reality when someone returns.

Reduced motion. Step transitions can slide panels. Under prefers-reduced-motion: reduce, swap content without sliding.

Optional steps. Mark optional screens in the label, like Review (optional), so people know they can skip without hunting for a skip link buried in the footer.

Common questions

How many steps can a stepper have?
Past about five, the strip gets crowded on a phone and people lose track of labels. Split into two flows or drop optional steps to the review screen instead of giving every micro-task its own step.
Can people skip ahead?
Only to steps they already completed, or to steps that do not depend on earlier answers. Skipping forward into a step with missing data produces validation errors on the review screen, which is harder to fix than blocking the skip.
Stepper or tabs?
Tabs switch peer panels on one page. A stepper advances a pipeline where order matters, like checkout or onboarding. If someone can jump to step three without visiting step two, you probably have tabs.
Should the stepper be clickable?
Completed steps should be clickable so people can fix an earlier answer. The current step is marked but not a link to itself. Future steps stay disabled until the flow reaches them.
Vertical or horizontal?
Horizontal across the top suits short flows on desktop. Vertical beside the content suits long labels or many steps. Pick one orientation per product, not both in different flows.
What markup should a stepper use?
An ordered list with aria-current="step" on the active item. Screen readers announce step position when the roles are honest. Avoid div-only steppers with no list semantics.

Last reviewed 26 AUG 2026