Accessible breadcrumbs
Updated October 14, 2026 · 5 min read
Breadcrumbs show where a page sits in the shop: Home › Women › Shoes › Ankle boots. They are simple, but often built as plain text with separators that screen readers read aloud. This page shows the APG pattern. It is part of the accessible UI patterns series.
When to use breadcrumbs
The APG defines a breadcrumb trail as "a list of links to the parent pages of the current page in hierarchical order". Use breadcrumbs on sites with several levels — categories, sub-categories, product pages, help articles. They are usually placed before the main content. On a flat site with two levels they add little.
Relevant WCAG criteria
WCAG does not require breadcrumbs, but if you have them, these criteria apply:
- 1.3.1 Info and Relationships (A): the trail is a list in a navigation landmark, not loose text.
- 2.4.5 Multiple Ways (AA): breadcrumbs can be one of the ways to find pages, together with menus, search and a sitemap.
- 2.4.4 Link Purpose (In Context) (A): link texts are the page names.
- 4.1.2 Name, Role, Value (A) and 1.4.1 Use of Color (A): the current page is identified in code and not only by colour.
- 3.2.3 Consistent Navigation (AA): the trail appears in the same place on every page.
- 2.5.8 Target Size (Minimum) (AA): short breadcrumb links on mobile need enough size or spacing.
- 1.4.10 Reflow (AA): long trails wrap on narrow screens.
Code example
<nav aria-label="Breadcrumb" class="breadcrumb">
<ol>
<li><a href="/en/">Home</a></li>
<li><a href="/en/women">Women</a></li>
<li><a href="/en/women/shoes">Shoes</a></li>
<li><a href="/en/women/shoes/ankle-boots" aria-current="page">Ankle boots</a></li>
</ol>
</nav>
<style>
.breadcrumb ol { display: flex; flex-wrap: wrap; list-style: none; padding: 0; }
.breadcrumb li + li::before {
content: "";
display: inline-block;
margin: 0 .5em;
width: .4em; height: .4em;
border-top: 1px solid currentColor;
border-right: 1px solid currentColor;
transform: rotate(45deg); /* a chevron drawn with borders: nothing to read aloud */
}
.breadcrumb [aria-current="page"] { font-weight: 600; text-decoration: none; }
</style>
What the APG specifies:
- The trail "is contained within a navigation landmark region", labelled with
aria-labeloraria-labelledby. - "The link to the current page has
aria-currentset topage." If the current page is not a link but plain text,aria-currentis optional. - The APG example structures the links as an ordered list, which tells screen reader users how many levels there are, and adds the separators with CSS — a skewed border — so they are "not represented in the accessibility tree".
Using nav gives users a landmark they can jump to; the label "Breadcrumb" separates it from the main navigation and the footer navigation.
Keyboard interaction
The APG lists keyboard interaction for breadcrumbs as "not applicable": they are ordinary links.
| Key | Function |
|---|---|
| Tab / Shift + Tab | Moves through the breadcrumb links |
| Enter | Follows the link |
| Screen reader landmark navigation | Jumps to the "Breadcrumb" navigation |
Common mistakes on online shops
- Separators in the HTML ("/", "»", ">") that screen readers read between every link.
- A
divof links withoutnavand without a list, or anavwithout a label next to two other unlabellednavelements. - The current page shown only by grey colour, without
aria-currentor another visual difference. - Breadcrumbs that reflect the browsing path ("Back to search results") on some pages and the category tree on others, which breaks consistency.
- Truncated trails on mobile that hide the parent categories with no way to reveal them.
- Tiny links packed together on mobile.
- Structured data for breadcrumbs that does not match the visible trail — not an accessibility issue in itself, but a sign the two were built separately.
What automated checks catch vs manual testing
| Automated (axe-core rule) | What it finds |
|---|---|
link-name |
Breadcrumb links without a name, for example an icon-only "Home" |
list, listitem |
A list that contains something other than list items, list items outside a list |
aria-valid-attr-value |
aria-current with an invalid value |
landmark-unique |
Several navigation landmarks without unique names (advice) |
color-contrast |
Grey breadcrumb text with too little contrast |
target-size |
Breadcrumb links that are too small and too close |
All are cards in our rule library. Manual testing: check with a screen reader that the trail is announced as a navigation named "Breadcrumb" with a list of the right number of items, that separators are silent and that the current page is identified; check that the trail wraps at 320 CSS pixels and is the same on every page.
Run the free one-page check on a category page. It is an automated check, not a full audit.
Frequently asked questions
Does WCAG require breadcrumbs?
No. Breadcrumbs are one way to help users find their position. 2.4.5 Multiple Ways asks for more than one way to find a page within a set of pages; breadcrumbs can support that together with navigation and search, but they are not required.
How do I mark up an accessible breadcrumb?
A nav element labelled "Breadcrumb" with aria-label, an ordered list of links to the parent pages, and aria-current="page" on the link to the current page. That is the APG breadcrumb pattern.
Should the current page in a breadcrumb be a link?
Either is fine. If it is a link, it needs aria-current="page". If it is plain text, the APG says aria-current is optional.
How should separators be added?
With CSS, for example a border or a pseudo-element, so that screen readers do not read "slash" or "greater than" between the links. If the separator is in the HTML, hide it with aria-hidden="true".
Can an automated check test breadcrumbs?
It finds links without names, broken list structure, invalid aria-current values and navigation landmarks without unique names. Whether the trail matches the site structure needs a person.
Sources
- W3C WAI, APG Breadcrumb pattern: https://www.w3.org/WAI/ARIA/apg/patterns/breadcrumb/
- W3C WAI, APG Breadcrumb example: https://www.w3.org/WAI/ARIA/apg/patterns/breadcrumb/examples/breadcrumb/