Eunomia v1.1.0
AllAngularReactNext.jsJavaScriptVue
EunomiaSalmonForestVioletOceanGoldFireCustom…
🇬🇧 English🇫🇷 Français

Breadcrumb

Breadcrumb displays a trail of links tracing the current page's position within a site's hierarchy, from the root down to where someone actually is. Each step is a plain <a> you write yourself, so your framework's own link component keeps its client-side navigation and prefetching. The final step is the current page.

Overview API Examples Accessibility
Home Catalogue Kitchen mixer tap

When to use

Add a breadcrumb once someone can be more than one level deep in your site, such as a product inside a category or a document inside a folder, so they can always see where they landed and step back without hitting the browser's back button. Skip it on flat, top-level pages where there's nowhere meaningful to trace back to, and never let it be the only way to navigate. It should complement a real primary navigation, not replace one.

Install & usage

Pick a framework in the toolbar above and these snippets adapt.

npm install @eunomia/elements
import "@eunomia/elements/breadcrumb.js";
<eun-breadcrumb aria-label="Breadcrumb">
  <a href="/">Home</a>
  <a href="/catalogue">Catalogue</a>
  <span>Kitchen mixer tap</span>
</eun-breadcrumb>

Importing the file registers <eun-breadcrumb> as a custom element, with no further setup needed. Each direct child is one step: an <a>, or a plain element such as a <span> for a step that isn't a page. The breadcrumb wraps every step in its own list item, adds the separators, and marks the last step as the current page.

Guidance

  • Use eun-breadcrumb on any page nested more than one level deep, so people can see where they are and jump back to an ancestor page in one click
  • Write each step with your framework's own link component, so navigation stays client-side without any router bridge
  • Keep labels short, since long ones truncate with an ellipsis past --breadcrumb-item-max-width (see the Examples tab)
  • Pair an icon with visible text, since an icon alone has no accessible name (see the Accessibility tab)
  • Using it on top-level pages, since a one- or two-step trail rarely earns its place
  • Wrapping the steps in another element, such as a <div> or a fragment that renders one: each direct child is a step, so the wrapper would become a single step
  • Using it as the page's only means of navigating back. Pair it with a proper primary navigation, not instead of one

Live testing

Properties

eun-breadcrumb only needs its steps as children, and aria-label (defaults to "Breadcrumb", in the active locale).

Breadcrumb <eun-breadcrumb>

Attributes

NameTypeDefaultDescription
aria-labelstring—The accessible label for the navigation landmark. Defaults to the localized string for the current locale (English: "Breadcrumb")

Import the exact TypeScript type behind any property above, see Types.

Properties

JS-only — no matching HTML attribute, set these from a script or a template binding.

NameTypeDefaultDescription
resolvedLocale—This instance's own `locale` when set, the shared default locale otherwise. Used for `Intl` formatting, so dates and numbers follow the same locale as dictionary.
dictionary—This instance's locale-resolved string dictionary — see the class doc for the resolution order.

Slots

NameDescription
(default)The steps, one per direct child : an anchor, or a plain element for an unlinked step

CSS custom properties

NameDescription
--breadcrumb-font-sizeSets the font size of the whole trail, 14px by default
--breadcrumb-link-colorSets the color of linked steps
--breadcrumb-link-color-hoverSets the color of linked steps on hover or focus
--breadcrumb-link-text-decorationSets the text decoration of linked steps, underline by default, such as none
--breadcrumb-link-text-decoration-hoverSets the text decoration of linked steps on hover or focus, underline by default
--breadcrumb-current-colorSets the color of the current page and unlinked steps
--breadcrumb-focus-outline-colorSets the color of a linked step's focus outline
--breadcrumb-separatorSets the separator between steps, as a quoted CSS string, such as '>'
--breadcrumb-separator-colorSets the color of the separator
--breadcrumb-separator-gapSets the gap around the separator
--breadcrumb-item-max-widthSets the maximum width of each step, beyond which its label truncates with an ellipsis
--breadcrumb-gapSets the row gap, used when the trail wraps onto multiple lines
--breadcrumb-transition-durationSets the duration of the link hover color transition

Basic

Home Catalogue Kitchen mixer tap
<eun-breadcrumb aria-label="Breadcrumb">
  <a href="/">Home</a>
  <a href="/catalogue">Catalogue</a>
  <span>Kitchen mixer tap</span>
</eun-breadcrumb>

Steps

Two steps

Home Catalogue
<eun-breadcrumb aria-label="Breadcrumb">
  <a href="/">Home</a>
  <span>Catalogue</span>
</eun-breadcrumb>

Unlinked intermediate step

Any element other than a link renders as plain text, useful for a category that groups pages without being a page itself. Mark the actual current page with aria-current="page" here, since the breadcrumb only marks the last step when no step is marked yet.

Home Faucets Kitchen mixer tap
<eun-breadcrumb aria-label="Breadcrumb">
  <a href="/">Home</a>
  <span>Faucets</span>
  <span aria-current="page">Kitchen mixer tap</span>
</eun-breadcrumb>

Linked current page

The current page can stay a link, for instance to reload it with its default filters. It's then styled as the current page rather than as a link.

<eun-breadcrumb aria-label="Breadcrumb">
  <a href="/">Home</a>
  <a href="/catalogue">Catalogue</a>
</eun-breadcrumb>

Display

Long labels truncate

Each step truncates with an ellipsis past --breadcrumb-item-max-width (240px by default), so one long label can't push the trail off-screen.

Custom separator

--breadcrumb-separator takes any quoted CSS string.

Home Catalogue Kitchen mixer tap
<eun-breadcrumb aria-label="Breadcrumb" style="--breadcrumb-separator: '>';">
  ...
</eun-breadcrumb>

Integration

SPA navigation

The steps are your own links, rendered in the light DOM: a router's link component, such as Next's <Link>, React Router's <Link>, Vue's <router-link> or Angular's routerLink, handles the click itself, with client-side navigation and prefetching. eun-breadcrumb fires no event of its own, and needs no router bridge.

import Link from "next/link";

<eun-breadcrumb aria-label="Breadcrumb">
  <Link href="/">Home</Link>
  <Link href={`/categories/${category.slug}`}>{category.name}</Link>
  <span>{article.name}</span>
</eun-breadcrumb>;

Server-side rendering

Before the breadcrumb upgrades, its steps are plain links run together, with no separator. Link breadcrumb-ssr.css in the page's <head> to draw the final trail from the first paint:

<link
  rel="stylesheet"
  href="node_modules/@eunomia/elements/dist/ssr/breadcrumb-ssr.css"
/>

A bundler that resolves package exports can reach it as @eunomia/elements/breadcrumb-ssr.css.

It lays the steps out in a row with their separators, styles the links and the current page, and covers the --breadcrumb-* properties. A step long enough to truncate counts its separator in its maximum width until the upgrade, so the steps after it can move slightly then.

Custom

Override the --breadcrumb-* CSS variables, listed in full in the API tab. Links are underlined by default: --breadcrumb-link-text-decoration: none removes it, and the underline still shows on hover.

Home Catalogue Kitchen mixer tap
<eun-breadcrumb class="custom-breadcrumb" aria-label="Breadcrumb">
  ...
</eun-breadcrumb>
.custom-breadcrumb {
  --breadcrumb-link-color: #be185d;
  --breadcrumb-link-color-hover: #9d174d;
  --breadcrumb-link-text-decoration: none;
  --breadcrumb-separator: ">";
}

The custom properties that change colors, borders, shadows and corners, at a glance. The API tab lists every property of the component.

Variable Sets
--breadcrumb-link-color Sets the color of linked steps
--breadcrumb-link-color-hover Sets the color of linked steps on hover or focus
--breadcrumb-current-color Sets the color of the current page and unlinked steps
--breadcrumb-focus-outline-color Sets the color of a linked step's focus outline
--breadcrumb-separator-color Sets the color of the separator

Keyboard interactions

eun-breadcrumb adds no custom keyboard handling of its own. Every step is your own link (or plain text), so standard link navigation already applies:

Key Action
Tab / Shift+Tab Moves focus between linked steps, in trail order
Enter Follows the focused step's link

Semantics and screen readers

Aria attributes and rules

  • Rendered as <nav aria-label="Breadcrumb"> wrapping an <ol role="list">, the standard breadcrumb pattern recommended by the WAI-ARIA APG. Its default label follows the active locale, and aria-label overrides it for a specific context.
  • role="list" is set explicitly despite <ol> having it implicitly: Safari drops the implicit role once list-style: none is applied (needed here for the visual flex layout), which would otherwise silently skip the list for VoiceOver users.
  • Each step sits in its own <li> through its own slot, so assistive technology reads a list with one item per step, while the links themselves stay in your markup.
  • The separators are aria-hidden, so they're never read out.

The current page

The current page carries aria-current="page". Unless a step already sets it, the breadcrumb marks the last step itself, and moves that mark along when the steps change. Set it yourself when the current page isn't the last step, or to have it in the server HTML before the component loads.

Label accessibility

A step's accessible name comes entirely from its content. An icon-only step has no accessible name, since eun-icon renders with aria-hidden="true" by design (see the Icon component). Always pair an icon with visible text, or set aria-label on the link if the text truly can't be visible.

Long labels

Labels truncate visually past --breadcrumb-item-max-width, but the full text stays in the DOM. Screen readers always read the complete label, regardless of how much of it is visually clipped.

Reference links

WAI-ARIA Authoring Practices: Breadcrumb Pattern
WAI Web Accessibility Tutorials: Labeling Controls