Accessible Checkout Step Indicators: What aria-current=“step” Actually Requires
Quick answer: A multi-step checkout tracker — “Cart → Shipping → Payment → Review,” with the
current step visually highlighted — needs aria-current="step" on the element representing where
the shopper currently is. The WAI-ARIA 1.2 specification
defines it directly: step is a listed token value of the aria-current attribute, described as
representing “the current step within a process,” and the spec’s own usage note names this exact
component: “a step token used to indicate a link within a step indicator for a step-based process,
where the link is visually styled to represent the current step.” Without it, a screen reader user
gets a row of text or links that all sound identical, with no indication which one is “you are
here.”
This article covers technical accessibility practice, not legal advice — it explains what a step-indicator component needs to meet WCAG 2.1 AA and how to implement it, not whether a specific site carries legal risk.
Why a color change alone doesn’t communicate anything
A typical checkout step tracker marks the current step with a filled circle, a bolder color, or an underline, and marks completed steps with a checkmark. All of that is CSS and an icon swap — real information for a sighted user, and nothing at all for a screen reader user unless the markup says so explicitly. This is the same gap WCAG SC 1.3.1 Info and Relationships (Level A) exists to close: “information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.” A shopper on a screen reader tabbing through “Cart, Shipping, Payment, Review” — four links or list items that all read the same way — has no way to tell that “Shipping” is the step they’re currently on, versus a step they’ve already completed or haven’t reached yet.
The token built for exactly this case
MDN’s aria-current reference
doesn’t describe this in the abstract — it names the e-commerce case directly. Its description of
the step value: “Represents the current step within a process such as the current step in an
enumerated multi step checkout flow.” Its usage guidance is just as specific: “In a multi step
based process with a step indicator such as a multi-page survey or a multi step checkout or
registration process, when the current step icon is visually different to represent that it is
the current step, that icon’s container should have aria-current="step" for assistive technology
users who may not be able to ‘see’ the visual difference.”
step is one of a fixed set of enumerated aria-current tokens defined in the WAI-ARIA 1.2
spec — page, step, location, date, time, true, and
false — each aimed at a different kind of “current item in a set.” page is what Quietramp’s
breadcrumb-navigation article covers, for
the current page in a breadcrumb trail. step is the same underlying mechanism aimed at a
different kind of set: not pages in a site hierarchy, but steps in a single task. Per the spec,
“authors SHOULD only mark one element in a set of elements as current with aria-current” — one
step per tracker, not the current step plus every completed one.
One implementation detail worth flagging directly: aria-current isn’t usable everywhere. MDN’s
own reference lists it as unsupported “for elements with the role of gridcell, option, row
and tab” — a step indicator built from tab-like markup (role="tab" on each step) can’t carry
aria-current on those elements; a plain list or set of links doesn’t have that restriction.
The pattern in practice
The APG doesn’t publish a dedicated “stepper” design pattern the way it does for breadcrumbs, tabs, or dialogs — a step indicator is closer to a specialized navigation list than a full interactive widget, so the fix is markup and one attribute, not a keyboard model to build from scratch:
<nav aria-label="Checkout progress">
<ol>
<li><a href="/cart">Cart</a></li>
<li aria-current="step"><a href="/checkout/shipping">Shipping</a></li>
<li><span>Payment</span></li>
<li><span>Review</span></li>
</ol>
</nav>
A few details in that markup are load-bearing, not decorative:
aria-current="step"sits on the current step, not on every step. If the tracker’s real visual behavior lets a shopper click back to a completed step, that step stays a real<a>; a step not yet reachable (Payment, Review, before Shipping is done) is reasonably rendered as plain text rather than a dead link — a<span>, not an<a href="#">that goes nowhere.- The list stays a real
<ol>, for the same SC 1.3.1 reason a plain-text breadcrumb trail fails without one: a run of<div>s or bare links with CSS-only spacing gives a screen reader no indication there are four related items in a specific order. - The
<nav>gets its own accessible name (aria-label="Checkout progress"), distinguishing it from the site’s primary navigation landmark the same way a breadcrumb’s<nav>does.
Three failures that show up before aria-current is even relevant
aria-current="step" is the finishing touch on a step indicator, not the whole fix. It’s common to
find one of these three problems underneath it:
No accessible name on icon-only steps. Some trackers render each step as a numbered circle
with no visible text label at all — just “1,” “2,” “3” inside styled dots, with the step names
shown only as a tooltip or omitted entirely on mobile. WCAG SC 4.1.2 Name, Role,
Value (Level A) requires that
“for all user interface components… the name and role can be programmatically determined” — a
step represented only by a number, with the actual step name never exposed in text or an
aria-label, gives a screen reader user “2” with no way to know that means “Shipping.”
Non-descriptive step labels. WCAG SC 2.4.6 Headings and Labels (Level AA) requires that “headings and labels describe topic or purpose.” “Step 2” describes a position, not a purpose — pairing the number with the actual step name (“Step 2 of 4: Shipping,” not just “Step 2”) is what actually orients a user, sighted or not, to what happens on that step.
A tracker built entirely from background images or a canvas/SVG graphic, with no underlying text or list markup at all. This fails SC 1.3.1 outright — there’s no structure to programmatically determine because there’s no markup describing one, regardless of how the visual design looks.
What a scan catches, and what a person has to check
An automated scanner can confirm a step indicator has list markup and that link text isn’t empty.
It generally can’t confirm that exactly one step carries aria-current="step" at the right moment
(a common bug: the attribute stays hard-coded on step one instead of updating as the shopper
progresses), or that a screen reader actually announces “current step” language when it lands on
that item — both require walking the flow with a screen reader, not just parsing the rendered DOM
once.
FAQ
Does every step in the tracker need to be a link? No. The current step and any completed step a shopper can navigate back to are reasonably links; a step that hasn’t been reached yet is often better as plain text, since a link that goes nowhere useful (or skips required steps) creates its own confusion.
Is aria-current="step" required for WCAG 2.1 AA conformance?
aria-current itself isn’t a named WCAG success criterion — it’s an ARIA attribute, one
documented technique among several for satisfying SC 4.1.2’s requirement that current state be
programmatically determinable. A step indicator could pass 4.1.2 a different way (an
aria-label="Shipping, current step" on the element, for example), but aria-current="step" is
the purpose-built, standard mechanism for it.
Does this overlap with the breadcrumb article’s aria-current="page" pattern?
They’re the same underlying attribute applied to a different kind of set — a breadcrumb tracks
position in a page hierarchy (page), a step indicator tracks position in a single task or process
(step). The mechanism is identical; which token applies depends on what the “current item” is
current within.
Get your checkout flow checked by a person, not just a parser
Quietramp’s $890 audits include a manual pass through checkout-specific components like step
indicators — confirming the current-step attribute actually updates as a real shopper moves
through the flow, not just that a <nav> and <ol> exist somewhere in the markup. See a real
sample report or check pricing — $890 one-time, $99/month
for ongoing re-checks after fixes ship.
This is educational content about technical accessibility practice, not legal advice. Meeting WCAG 2.1 AA does not constitute a legal compliance determination under the ADA or any other standard — consult qualified counsel for legal risk questions.
This article was drafted with AI assistance and reviewed by a person for accuracy before publication.