figma guide

Designing progress indicators and steppers in Figma: patterns, states, and handoff

Design linear progress bars, circular spinners, and multi-step steppers in Figma with determinate vs indeterminate states, labels, and Dev Mode handoff specs.

Published
Updated
Jun 10, 2026
Read time
8 min
Level
Beginner

Quick answer

Progress indicators in Figma show task completion—either determinate (known percentage) or indeterminate (unknown duration). Steppers show discrete steps in a multi-page flow (checkout, onboarding, settings wizard). Build linear bars and circular indicators as small published components; build steppers as horizontal or vertical step lists with variants for state=complete | current | upcoming | error. Document whether users can click ahead, what happens on back, and validation gates in Dev Mode. Pair with forms, loading states, and the Figma guides hub.


Who this is for

  • Product designers shipping onboarding wizards, checkout flows, and file-upload UIs.
  • Design system teams separating progress bars (within a step) from steppers (across steps).
  • Engineers implementing aria-valuenow, step validation, and non-linear navigation rules.

Progress bar vs stepper vs spinner

PatternShowsBest forAvoid when
Linear progress bar% complete within one taskFile upload, install, profile %Multi-page flow navigation
Circular progressCompact % or indeterminateButtons, avatars, tight spacesLong-form wizards
Indeterminate spinnerActivity without %Unknown wait timeUpload with known file size
StepperSteps across a flowCheckout, onboarding, settingsSingle-page form
Skeleton screenContent placeholderPage loadMid-step percentage

Verdict: use a stepper when the user crosses multiple screens; use a progress bar when one screen tracks completion of a single task. Use skeletons for initial page loads—not steppers.


Linear progress bar anatomy

PartPurposeSpec tip
TrackBackground railFull width; 4–8px height
FillCompleted portionRounded ends; animate width in code
Label (optional)“68%” or “3 of 5”Above or inside bar for large bars
Helper text”Uploading invoice.pdf”Below bar; truncate long filenames
ProgressBar / Linear
├── Variant: type=determinate | indeterminate
├── Variant: size=sm | md | lg
├── Property: hasLabel=true | false
├── Layer: Track (full width, radius full)
│   └── Fill (width = percentage; bind to variant or manual)
└── Label (optional, text/body-sm)

Bind track and fill to semantic tokensprogress/track, progress/fill. Use brand primary for fill; neutral gray for track.


Determinate vs indeterminate

TypeWhen to useDesign note
DeterminateKnown total (file size, steps completed)Show percentage or fraction
IndeterminateUnknown duration (API call, processing)Animated shimmer or looping bar—no fake %

Do not show “47%” on an indeterminate task—it erodes trust. Switch from indeterminate to determinate when the app knows progress.


Circular progress anatomy

PartPurposeSpec tip
Track ringBackground circle2–4px stroke
Progress arcCompleted arcStroke-dasharray in code
Center label% or iconOptional; 32–48px total size

Use circular progress inside buttons (“Saving…”), avatar uploads, and dashboard widgets. Keep minimum 24px diameter for visibility.


Stepper anatomy: horizontal

PartPurposeSpec tip
Step indicatorNumber or checkmark in circle24–32px
Connector lineBetween steps2px; filled for completed segments
Step label”Shipping”, “Payment”Below indicator; truncate on mobile
Optional descriptionSubtitle per stepHide on compact mobile
Stepper / Horizontal
├── Variant: stepState=complete | current | upcoming | error
├── Property: showDescription=true | false
├── Layer: Step row (vertical auto layout per step)
│   ├── Indicator circle (number or ✓)
│   ├── Label (text/label-md)
│   └── Description (optional, text/body-sm)
└── Connector (horizontal line between steps)

Publish one step component with state variants; repeat instances in a horizontal auto layout with connectors between them.


Stepper anatomy: vertical

Use vertical steppers for:

  • Desktop checkout with room for descriptions
  • Settings wizards with long step titles
  • Timeline-style onboarding

Same complete | current | upcoming | error states. Connector runs vertically between indicators. On mobile, collapse to horizontal compact (numbers only) or a “Step 2 of 4” text summary.


Step states

StateIndicatorConnector afterLabel style
CompleteCheckmark in filled circleFilled / brand colorDefault or muted
CurrentNumber in filled circleUnfilled aheadBold
UpcomingNumber in outline circleUnfilledMuted
Error! or number in error colorUnfilled or errorError token + helper text

Pair error steps with inline alerts on the step content—not only a red circle users cannot interpret.


RuleDesign decision
Click ahead to future steps?Usually no until current validates
Click back to completed steps?Usually yes; preserve entered data
Skip optional steps?Show Skip link; mark step complete
Linear only?Note if sidebar nav is disabled mid-flow
Save and exit?Secondary action on every step

Write these rules in the stepper component description—engineers will otherwise allow free navigation that breaks validation.


Steppers with forms

Each step frame should contain:

  1. Stepper header (instance)
  2. Step content (form fields from forms guide)
  3. Footer actions: Back (secondary), Continue (primary), optional Save draft
Step typePrimary button label
Middle steps”Continue” or “Next”
Final step”Submit”, “Place order”, “Finish”
Payment”Pay now”

Disable Continue until required fields pass validation—show disabled button state in the component set.


Progress within a step

Combine stepper + linear bar when one step has sub-tasks:

  • Step 3: Upload documents — bar shows 2 of 4 files uploaded
  • Profile setup — bar shows profile 80% complete before “Continue” enables

Keep the bar inside the step content area, not in the stepper header, to avoid two competing progress metaphors at the same level.


Accessibility

ElementRequirement
Linear barrole="progressbar", aria-valuenow, aria-valuemin, aria-valuemax
Indeterminate bararia-busy="true"; no misleading valuenow
Stepperaria-current="step" on current step
Error steparia-invalid + linked error message
ColorDo not rely on green/red alone—use icons (✓, !)

Announce step changes with a live region in engineering (“Step 2 of 4: Payment”). Minimum 44px touch targets on step indicators if they are clickable.


Prototyping limits

Figma cannot enforce validation between steps. For reviews:

  1. Build frames: Step 1, Step 2, Step 3 complete.
  2. Prototype Continue → next frame; Back → previous.
  3. Add a disabled Continue frame showing validation failure.
  4. Note: “Engineering: block advance until schema passes.”

For determinate bars, show 0%, 50%, and 100% as separate component variants—not a single animating layer.


Handoff to engineering

DeliverableWhere it lives
Step count and labelsStepper component properties
Navigation rules (ahead/back)Component description
Validation per stepLinked form spec or table
Progress calculationDev Mode note (file bytes, fields filled)
Mobile collapse behaviorsm artboard with compact stepper
Error recoveryError variant + alert placement

Include steppers in your Dev Mode handoff checklist. Publish under Patterns / Stepper and Patterns / Progress in your team library.


Real-world examples

E-commerce checkout (horizontal stepper)

Steps: Cart → Shipping → Payment → Review. No click-ahead. Back preserves cart. Final step uses modal confirm for place order.

File upload (linear determinate bar)

Single page; bar fills by bytes uploaded. Switch to error state with inline alert on failure; retry action resets bar.

Onboarding wizard (vertical stepper)

Four steps with descriptions. Optional “Skip tour” on step 1. Last step shows empty state CTA to create first project.

Cross-link wireframing when step flows are still in lo-fi review.


Common mistakes

MistakeConsequenceFix
Fake % on unknown waitsUsers lose trustIndeterminate until known
Stepper for single long formUnnecessary frictionOne page + section headings
Clickable future stepsBroken validationDisable or hide ahead navigation
No error state on stepsUsers stuckerror variant + message
Tiny step circles on mobileMis-taps32px min or compact text mode
Two progress bars stackedVisual noiseOne metaphor per level
Step labels truncate to ”…”Users lostShort labels; tooltip on hover
Spinner for 30s uploadNo sense of timeDeterminate bar with %

FAQ

Should the stepper and progress bar share one component?

No. Steppers navigate across pages; progress bars track within a task. Share color tokens and size scale only.

How is this different from loading skeletons?

Skeletons replace content layout during fetch. Progress bars show task completion for actions the user initiated (upload, submit, install).

Show step numbers or icons only?

Numbers for flows up to ~5 steps. Switch to icons + short labels only when steps are universally understood (✓ cart, card, truck). Always include a text label for accessibility.

Include a percentage in onboarding steppers?

Usually no—use “Step 2 of 4” text instead. Percentages fit profile completion or upload contexts, not arbitrary wizard pages.


Bottom line

Use linear or circular progress for single-task completion (known or unknown duration) and steppers for multi-step flows with clear complete, current, upcoming, and error states. Document navigation rules, validation gates, and mobile collapse in Dev Mode. Continue with forms, modals for final confirms, and the tutorials hub.

Share on X

§ Keep reading

Related guides.