Accessibility

An accessible breadcrumb

An accessible breadcrumb is a named nav with an ordered list, aria-current on the last item and JSON-LD carrying the same hierarchy as the page.

Key points

  • A breadcrumb belongs in a nav with aria-label and an ordered list: structure comes from the HTML, not from attributes.
  • The last item carries aria-current="page" and is not a link to itself.
  • Separators are decorative and must stay out of the link's accessible name.

An accessible breadcrumb is a <nav> with a name, an ordered list of links and aria-current="page" on the last item; the rest is repeating the same hierarchy in JSON-LD. No extra roles, no tabindex: the semantics come from native elements.

The minimum structure

The ordered list is not a detail: it states how many items there are and in what order, and the screen reader announces it as “list of 3 items”. The name on the nav separates this navigation from the main one when the user opens the landmark list.


  
    Home
    Components
    Accessibility
  

Three details that break it

  • Announced separators: a chevron written as text inside the link joins the accessible name. Use ::before in CSS, or aria-hidden="true" on the separator.
  • Last item as a link: a link to the page you are on is a control that does nothing. Plain text with aria-current="page".
  • Generic names: “Continue” or “Here” do not describe the destination and break 2.4.4. Every item must make sense read on its own.

JSON-LD with the same hierarchy

The BreadcrumbList structured data must describe the same items, in the same order, with position starting at 1. If the visible page and the JSON-LD diverge, the markup is a false statement: no structured data is better. The full format, with the checks, is in BreadcrumbList without errors.

{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com/" },
    { "@type": "ListItem", "position": 2, "name": "Components", "item": "https://example.com/components" },
    { "@type": "ListItem", "position": 3, "name": "Accessibility" }
  ]
}

The EneUI catalogue

The verified record is breadcrumb-01 by flx, described as “links with a current page and chevron separators”: that is the case here, with a breadcrumb registry dependency and no external package. The other views are in navigation and accessibility. Checked on 1 November 2026 against 111,985 components.

The limitation

A breadcrumb orients, it does not replace the page title or a readable URL structure, and it does not help someone arriving from search: that person lands mid-hierarchy with no path. On a two-level site the list adds noise; on a five-level site you must collapse it on mobile, but the current level has to stay visible.

Where to continue

The difference between roles, states and properties is in what ARIA is; the component checklist is in accessible React components. If you are comparing headless primitives for the navigation, read Radix, Base UI and React Aria.

Frequently asked questions

Does the breadcrumb nav need aria-label?

Yes, when the page has more than one nav. The name “Breadcrumb” separates this navigation from the main one in the landmark list.

Should the last item be a link?

No. It is the current page: plain text with aria-current="page", or a link carrying the same attribute if you want it clickable.

Should the screen reader announce the separators?

No. Put them in CSS with ::before or hide them with aria-hidden="true": a slash or chevron announced after every item makes the list unreadable.

Does WCAG require a breadcrumb?

No, no criterion demands one. If you build it, it must meet 1.3.1, 2.4.4 and 4.1.2 like any other navigation.

Must I show every level on mobile?

No, you can collapse the middle levels, but the first and last stay visible: without the current level the reader loses their place.