12 CSS Steppers
A stepper UI guides users through a multi-step flow — checkout, onboarding, signup wizard, survey — by visualising progress, current step, and what is still ahead. These 12 hand-coded steppers cover every production pattern: horizontal multi-step form wizard, numbered progress bar, e-commerce checkout with order summary, vertical timeline, animated icon steps, onboarding flow, breadcrumb tracker, validation states (success/error/warning), circular SVG progress, glassmorphism, dark mode, and animated connector lines. All semantic HTML with proper aria-current="step" and aria-valuenow, scoped .stp-NN__* class names so multiple steppers coexist on the same page, respect prefers-reduced-motion, and ship MIT-licensed. 11 use vanilla JavaScript for step navigation; 1 is fully static (Demo 03 — useful as a display-only checkout indicator).
Related22 CSS Progress Bars39 CSS Breadcrumbs32 CSS Timelines
Course pickPartner: Zero to Mastery
Affiliate linkWant to build production-ready CSS layouts, animations and UI from scratch?
You just browsed 12 steppers. Learn the Flexbox, Grid and animation thinking behind them, so the next component starts in your head, not in a copy-paste.
Every ZTM course in one membership: $25/month, paid yearly at $299 · 30‑day money-back guarantee
The CSS Bootcamp. We may earn a commission, at no extra cost to you.
02. CSS Step Progress Bar With Numbers (opens in a new tab)
03. CSS Checkout Stepper UI Component (opens in a new tab)
04. CSS Vertical Timeline Stepper (opens in a new tab)
05. CSS Animated Step Indicator With Icons (opens in a new tab)
06. CSS Onboarding Stepper Flow (opens in a new tab)
07. CSS Breadcrumb Style Step Tracker (opens in a new tab)
08. CSS Stepper With Validation States (opens in a new tab)
09. CSS Circular Step Progress Indicator (opens in a new tab)
10. CSS Glassmorphism Stepper UI (opens in a new tab)
11. CSS Dark Mode Stepper Component (opens in a new tab)
12. CSS Stepper With Connector Line Animation (opens in a new tab)
Frequently asked questions
What is a stepper UI component and when should I use one?
Should I build with Material UI's Stepper or vanilla CSS?
<Stepper> component is excellent if you're ALREADY on React + MUI — it ships with the rest of the MUI bundle (~95kb gzipped) so the marginal cost is zero. If you're NOT on React+MUI (Astro, Vue, Svelte, Rails ERB, plain HTML, WordPress) — installing MUI just for a stepper adds 95kb to your bundle for one component. This collection's 12 steppers drop in as semantic HTML + scoped CSS with zero framework dependencies. The 11 JS-enhanced demos use ~30-50 lines of vanilla JavaScript each — no library imports, no React/Vue/Angular tie-in. Aesthetically, the multi-step form (Demo 01), checkout (03), and circular progress (09) match MUI's production polish without the framework lock-in. Tailwind UI's stepper costs $300+ and ships as React JSX. Ant Design's <Steps>, Chakra UI's stepper, react-step-wizard, react-stepper-horizontal all add 8-50kb to your bundle. MIT-licensed, free, modify-and-resell allowed.How do I build a checkout stepper (Stripe / Shopify style)?
sessionStorage with the step data serialised as JSON. (b) Disable the active-tab click handler for FUTURE steps so users can't skip validation. (c) Show validation errors per step, not on the final review screen — the user lost context by then. ~50 lines of JS, fully framework-neutral.How do I add validation states to a stepper (success / error / warning)?
.is-done, .is-error, .is-warning, and .is-active. The standard "done / active / inactive" tri-state most steppers ship loses information when validation fails. Production-grade implementation: Done = green circle with white checkmark (✓), green connector line ahead; Error = red circle with white X mark (✕), red connector line to the next step, red helper text below the step label; Warning = amber circle with exclamation mark (!), amber connector, "some fields need review" text; Active = blue ring with the step number, gradient connector ahead in muted color; Inactive = gray circle with number, gray connector. JavaScript validates each step on "Continue" click and adds the appropriate class to the step element. Screen reader support: use aria-invalid="true" on error steps and aria-describedby pointing to the helper text. ~40 lines of JS.What's the difference between vertical and horizontal stepper layouts?
flex-direction from row to column. Most stepper libraries default to horizontal-only; vertical is the gap.How do I build an accessible stepper (keyboard navigation + screen readers)?
<nav aria-label="Steps"> as the outer wrapper, <ol> for the step list, <li> per step. Don't use divs styled as buttons — use real <button> elements so keyboard activation works automatically. (2) aria-current="step" on the active step. Screen readers announce "current step" alongside the step label so users know where they are without seeing the visual highlight. (3) aria-valuenow / aria-valuemax on the outer container — turns the stepper into a programmatic progress bar. For visitors using a screen reader, this announces "Step 3 of 5" as they navigate. (4) Keyboard arrow navigation. Left/Right arrow keys move between sibling steps; Enter activates. Tab order keeps the next/back buttons reachable. Focus management: when the active step changes, move focus to the new step's first focusable field — visitors using a keyboard never lose their place. Common mistake most tutorials make: relying purely on visual color difference (green checkmark) without text labels — colorblind users can't distinguish done from active. Always pair color with a glyph (✓ vs number) or aria-label text.How do I build a circular SVG progress stepper without a library?
<circle> elements at the same center+radius. The first (background) draws a full circle in a muted gray. The second (progress) has stroke-dasharray="circumference" (e.g. 188 for r=30) and stroke-dashoffset initially set to the full circumference (no visible stroke). JavaScript calculates current progress as (currentStep / totalSteps) * circumference and updates stroke-dashoffset = circumference - progress. The progress stroke fills clockwise as steps complete. Inside the circle, an <text> element shows "3/5" or a percentage. Cost comparison: react-circular-progressbar ships ~5kb minified + requires React. This demo's approach: ~30 lines of CSS + ~20 lines of vanilla JS, no library. The CSS transition: stroke-dashoffset 0.6s ease-out animates smoothly between step changes. Add transform-origin: center + transform: rotate(-90deg) on the progress circle so the stroke starts from the top (12 o'clock) instead of the right (3 o'clock default).How do I build an onboarding stepper (Notion / Linear / Vercel style)?
Will animating connector lines / step transitions hurt my Core Web Vitals INP score?
transform and opacity only. All 12 demos in this collection follow this — connector line growth (Demo 12) uses transform: scaleX(0) → scaleX(1) with transform-origin: left, not width: 0% → 100%. Scaling is GPU-accelerated on the compositor thread; animating width forces layout recalculation on every frame, costing 4-16ms per frame and tanking INP (Interaction to Next Paint), the Core Web Vital that replaced FID in March 2024. Two production gotchas specific to steppers: (a) SVG stroke-dashoffset animation (Demo 09 circular progress) IS expensive — each frame recalculates the stroke path. Mitigate by setting will-change: stroke-dashoffset on the progress circle so the browser promotes it to a GPU layer. (b) Animating background-color on step state change (gray → green when step completes) is a paint cost (~2-4ms per frame). Acceptable for one-off step transitions; would tank INP if you animated all 5 steps simultaneously. Demos in this collection sequence step state changes serially, not in parallel. Lighthouse mobile-profile scores: 95+ Performance on all 12 demos on a mid-tier Pixel 5 baseline.Which stepper should I use for my project?
aria-current="step" + aria-valuenow, respect prefers-reduced-motion, MIT-licensed.Related collections
15 CSS 3D Tilt Hover Cards
15 mouse-aware 3D tilt hover cards — e-commerce product spotlight, glassmorphism parallax team card, interactive pricing tier, holographic NFT collectible, pop-out mascot, dark tech grid with border glow, media player album art, blog article preview, cyberpunk neon glow, dashboard KPI widget, minimalist real estate, flip-to-back tilt, mobile app showcase, course learning card, and a Pure CSS touch-friendly tilt. Vanilla JS writes --rx/--ry/--mx/--my; all rendering stays in CSS on the GPU.
24 CSS Animated Cards
24 hand-coded CSS animated card patterns organised by what triggers the motion, not by card style. Scroll and entrance triggers: staggered grid reveals, @starting-style mount-in, scroll-driven scale and fade on animation-timeline: view(), View Transitions API card-to-detail morphs, blur-to-sharp lazy image loading, and FLIP re-layout when a filter changes. State-change triggers: add-to-cart success morph, like and save particle burst, expand and collapse to intrinsic height with calc-size(), swipe-to-dismiss on Pointer Events, and skeleton-to-loaded crossfade. Data-driven triggers: count-up KPI metrics, SVG sparkline draw-on-enter, and progress ring fill on load. Ambient idle loops: breathing glow, floating drift, animated gradient mesh backgrounds, conic rotating borders, auto-cycling testimonial decks, and live status pulses. Plus four hover patterns where the effect is the topic itself: cursor spotlight, holographic foil glare, corner ribbon slide, and horizontal accordion expand. Every card is scoped under a .ac-NN prefix for no-collision pasting, guards prefers-reduced-motion, animates compositor-only properties, and ports unchanged to React, Vue, Svelte, Astro, Next.js and Tailwind.
22 CSS Avatars
22 hand-coded CSS avatars for chat apps, team dashboards, comment threads, account menus, and social profiles. Covers circular and squircle shapes, gradient and conic story rings, hexagon clip-path crops, online status dots, notification count badges, verified checkmarks, stacked facepiles with plus-N overflow, initials fallbacks for users without photos, broken-image recovery, avatar pickers, and a size scale system where the ring, badge, and status dot all scale from a single custom property.









