Accessibility

What Breadcrumb does for you, and what it leaves to the page around it.

What it renders

Breadcrumb is a <nav> around an <ol>, one <li> per crumb. A crumb with href or path renders an <a>, and a crumb with neither renders a <span>. That is most of what a breadcrumb needs.
  • The list is a real list, so a screen reader announces it as one and gives the reader its length before reading the crumbs.
  • A crumb that is a link is a real link: it takes focus and Enter, and shows an outline on :focus-visible. Keep that outline. The hover color and background are not a focus ring.
  • It does not render a name for the landmark or a current-page marker. The next two sections cover both.

Naming the trail

There is no aria-label on the <nav>, so the landmark is announced as an unnamed navigation. A page with a sidebar and a breadcrumb then offers two navigations and no way to tell which is which.
  • Pass aria-label="Breadcrumb" on the component. It lands on the <nav>.
  • Leave the word “navigation” out of the name. The role already says it, and a reader hears it either way.
  • Where a page has more than one trail (a split view does), name each for what it is a trail through, instead of numbering them.

Marking the current page

There is no aria-current either. The last crumb looks different (its color, and it is not a link), and neither reaches a screen reader as “you are here”.
  • Put it on the item: { title: "Settings", "aria-current": "page" }. Items accept any aria-* key, and it lands on the crumb's <span> or <a>.
  • Mark one crumb, the last, and only when it is the page the reader is on.
  • Color is not the marker. The links are colorTextDescription and the last crumb is colorText, which only a sighted reader sees.

The separators are decoration

Every separator is its own <li aria-hidden="true">, whether it is the kit's chevron, a slash, or a node you passed yourself. Assistive tech never reads it.
  • Do not put meaning in a separator. One that says “in” or “of” says it to sighted readers only.
  • A separator you pass inherits the aria-hidden from the list item around it, so it needs none of its own, and an alt or a label on it would go nowhere.
  • separator="" changes nothing for a screen reader. It is a visual choice only.

An icon-only crumb

A crumb's accessible name is its text content. A home crumb built from a glyph alone is an unnamed link, and nothing warns about it.
  • Keep the word and hide it, inside the title: <Icon name="folder" /><span className="sr-only">Workspace</span>, or put an aria-label on the icon.
  • A title attribute on the anchor does not replace it. Not every reader reads it, and touch has no hover.
  • Give the crumb a visible word wherever there is room. The root is the crumb a lost reader reaches for, and it is the worst one to leave as a glyph.
One part of this component cannot be reached from a keyboard. Know it before you design around it.
  • An item's dropdown is mouse-only. The crumb that opens it is a <span> with no tabIndex, no role and no key handler, so it opens on hover or click and a keyboard user cannot open it. No trigger value changes that.
  • So never put a destination behind a crumb menu that is not reachable another way. Treat it as a shortcut over navigation that already exists somewhere on the page.
  • Contrast. The links, the separators and every crumb but the last are colorTextDescription, quieter than the page. Check a custom value against the surface the trail sits on, not against colorBgBase.
  • Motion. The only transition is color on a link, so there is nothing to put behind motion-safe:. A separator or an itemRender body that animates is yours to gate.