Skip to content

Breadcrumb

C-49 · Components · Navigation

All elements · Breadcrumb on the Components page

Last checked 2026-10-22 · Awaiting approval · Accessibility tests

Copies the bun run a11y:approve command for Breadcrumb.

Guidance

When to use

  • Show where a page sits in a hierarchy two or more levels deep, such as a case inside a program inside a department, or a document inside nested folders.
  • Put it at the top of the content area, above the page title, in the shell's content header (.qf-page-header).
  • Let users move up to any parent level in one step, especially when they arrived from search or a link and skipped the levels above.
  • Collapse the middle of a deep path (more than five levels) behind the __more button, keeping the root and the last two levels in view.

When to consider something else

  • When the hierarchy is the main way users move around the app, give it a Side navigation; breadcrumbs only add to it. See SideNavigation.
  • When the user moves through steps of a process rather than levels of a hierarchy, use Step indicator. See StepIndicator.
  • When the user browses and opens folders in place, use Tree. See Tree.
  • When the app is flat (every page one level below home), leave breadcrumbs out; a Home link would be the only crumb.

Usability

Do
  • Use each level's page title as its crumb, so the crumb and the heading the user lands on match.
  • Start at the app's root (Home, or the module's name) and end at the current page.
  • Show the current page as plain text, not a link, marked aria-current="page".
  • Let a long path wrap by default; use data-overflow="truncate" only in a fixed-height bar, and give each cut level a title with its full name.
  • Keep the trail the same on every visit to a page: it shows where the page lives, not the user's history.
Don’t
  • Don't use breadcrumbs as the only navigation.
  • Don't use them to show the steps of a form or the user's browsing history.
  • Don't hide the root or the current page when collapsing; hide only the middle.
  • Don't put actions (Edit, Share) in the trail.

Accessibility

Keyboard

Breadcrumb keyboard
Keys Action
Tab / Shift+Tab Moves through the links in order (and the … button when the path is collapsed); the current page is not focusable.
Enter Follows the focused link.
Enter or Space on … Reveals the hidden levels in place and moves focus to the first of them.

Roles and names

  • The block is a nav landmark named "Breadcrumb" with aria-label; it holds an ordered list (ol), so screen readers announce the number of levels.
  • Each level is a li.qf-breadcrumbs__item; every level but the last holds a link (.qf-breadcrumbs__link).
  • The last level is the current page: a span with aria-current="page", not a link.
  • Separators are drawn by CSS (::before), so they are not read and are not in the list's text.
  • The Home icon is aria-hidden; the link keeps its visible text "Home".
  • The collapse button is a button named "Show N more levels", with no aria-expanded (it is not a toggle); once pressed it is removed and the levels it hid are in the list.

Focus

  • Links and the … button show the shared focus ring.
  • Revealing the collapsed levels moves focus to the first of them, so focus is never lost with the removed button.

Other requirements

  • Links are underlined and in the link color (5.58:1 light, 9.23:1 dark), so they are not told apart by color alone (1.4.1); the current page is bold body ink.
  • Each link and the … button are at least 24px tall (--qf-breadcrumb-target), meeting 2.5.8.
  • By default the trail wraps at 320px and 400% zoom instead of scrolling (1.4.10).
  • A truncated level keeps its full name in the DOM, so screen readers read all of it; the title shows it to pointer users.

Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.

Accessibility tests

WCAG 2.2 AA · Passed

Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.

Breadcrumb test checklist
Area Automated A person checks
General Passed Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme.
Zoom Passed At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping.
Keyboard Passed Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order. (3 rows)
Screen reader Passed With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (6 items)

Approving. When the checklist passes on the checked run, record it with bun run a11y:approve -- breadcrumb --by "Your name" and commit a11y/approvals.json with the rebuilt pages. All test status

Package

Consumers link one stylesheet, css/classic/index.css, which includes every element. The files below are where this element is defined.

Breadcrumb package
Source css/classic/components/breadcrumb.css
Specimens also use Box · Button · Card · Chip · Icon · Table · Text · Toolbar
Sprites sprites/icons.svg
React Not yet available: the React binding has not started.

Latest updates

Breadcrumb latest updates
Date Version Breaking Description
2026-10-20 0.1 No Breadcrumb (C-49): the shell's .qf-breadcrumbs is cataloged and its rules move from composites/shell.css to components/breadcrumb.css; the content header (.qf-page-header) keeps using it. nav[aria-label="Breadcrumb"] › ol.__list › li.__item, every level a __link but the current page (aria-current="page"), CSS-drawn separators, 24px targets. Long paths wrap by default; data-overflow="truncate" keeps one line and cuts the levels above the current page first; a deep path hides its middle (__item[hidden]) behind a __more button that reveals it in place

All release notes