Breadcrumbs
The path from the root to the current page as an ordered list of links separated by slashes; the last item is the current page and not a link.
stable · light DOM · 4.0.0. Light DOM retains static content, native semantics, label relationships and host composition without duplicating controls.
Live variants
default
<j3w1-breadcrumbs id="example-breadcrumbs-default"><nav class="breadcrumbs" aria-label="Breadcrumb">
<ol class="breadcrumbs-list">
<li class="breadcrumbs-item"><a class="breadcrumbs-link" href="#example-breadcrumbs-default-bc-home">Home</a><span class="breadcrumbs-separator" aria-hidden="true">/</span></li>
<li class="breadcrumbs-item breadcrumbs-item-ellipsis" hidden=""><button class="breadcrumbs-ellipsis" type="button" aria-expanded="false" aria-label="Show 2 hidden levels" aria-controls="example-breadcrumbs-default-breadcrumb-levels-0">…</button><span class="breadcrumbs-separator" aria-hidden="true">/</span><ol id="example-breadcrumbs-default-breadcrumb-levels-0" hidden=""><li><a class="breadcrumbs-link" href="#example-breadcrumbs-default-level-0">Level 1</a></li><li><a class="breadcrumbs-link" href="#example-breadcrumbs-default-level-1">Level 2</a></li></ol></li>
<li class="breadcrumbs-item breadcrumbs-item-collapsible"><a class="breadcrumbs-link" href="#example-breadcrumbs-default-bc-projects">Projects</a><span class="breadcrumbs-separator" aria-hidden="true">/</span></li>
<li class="breadcrumbs-item breadcrumbs-item-collapsible"><a class="breadcrumbs-link" href="#example-breadcrumbs-default-bc-theme">Theme</a><span class="breadcrumbs-separator" aria-hidden="true">/</span></li>
<li class="breadcrumbs-item"><a class="breadcrumbs-link breadcrumbs-link-demo-target" href="#example-breadcrumbs-default-bc-settings">Settings</a><span class="breadcrumbs-separator" aria-hidden="true">/</span></li>
<li class="breadcrumbs-item"><a class="breadcrumbs-link breadcrumbs-current" href="#example-breadcrumbs-default-bc-appearance" aria-current="page">Appearance</a></li>
</ol>
</nav><p id="example-breadcrumbs-default-bc-home" tabindex="-1" class="j3w1-example-target">Example destination: bc home</p><p id="example-breadcrumbs-default-level-0" tabindex="-1" class="j3w1-example-target">Example destination: level 0</p><p id="example-breadcrumbs-default-level-1" tabindex="-1" class="j3w1-example-target">Example destination: level 1</p><p id="example-breadcrumbs-default-bc-projects" tabindex="-1" class="j3w1-example-target">Example destination: bc projects</p><p id="example-breadcrumbs-default-bc-theme" tabindex="-1" class="j3w1-example-target">Example destination: bc theme</p><p id="example-breadcrumbs-default-bc-settings" tabindex="-1" class="j3w1-example-target">Example destination: bc settings</p><p id="example-breadcrumbs-default-bc-appearance" tabindex="-1" class="j3w1-example-target">Example destination: bc appearance</p></j3w1-breadcrumbs>truncated
<j3w1-breadcrumbs id="example-breadcrumbs-truncated"><nav class="breadcrumbs" aria-label="Breadcrumb">
<ol class="breadcrumbs-list">
<li class="breadcrumbs-item"><a class="breadcrumbs-link" href="#example-breadcrumbs-truncated-bc-home">Home</a><span class="breadcrumbs-separator" aria-hidden="true">/</span></li>
<li class="breadcrumbs-item breadcrumbs-item-ellipsis"><button class="breadcrumbs-ellipsis" type="button" aria-expanded="false" aria-label="Show 3 hidden levels" aria-controls="example-breadcrumbs-truncated-breadcrumb-levels-0">…</button><span class="breadcrumbs-separator" aria-hidden="true">/</span><ol id="example-breadcrumbs-truncated-breadcrumb-levels-0" hidden=""><li><a class="breadcrumbs-link" href="#example-breadcrumbs-truncated-level-0">Level 1</a></li><li><a class="breadcrumbs-link" href="#example-breadcrumbs-truncated-level-1">Level 2</a></li><li><a class="breadcrumbs-link" href="#example-breadcrumbs-truncated-level-2">Level 3</a></li></ol></li>
<li class="breadcrumbs-item breadcrumbs-item-collapsible" hidden=""><a class="breadcrumbs-link" href="#example-breadcrumbs-truncated-bc-projects">Projects</a><span class="breadcrumbs-separator" aria-hidden="true">/</span></li>
<li class="breadcrumbs-item breadcrumbs-item-collapsible" hidden=""><a class="breadcrumbs-link" href="#example-breadcrumbs-truncated-bc-theme">Theme</a><span class="breadcrumbs-separator" aria-hidden="true">/</span></li>
<li class="breadcrumbs-item breadcrumbs-item-collapsible" hidden=""><a class="breadcrumbs-link" href="#example-breadcrumbs-truncated-bc-site">Site</a><span class="breadcrumbs-separator" aria-hidden="true">/</span></li>
<li class="breadcrumbs-item"><a class="breadcrumbs-link breadcrumbs-link-demo-target" href="#example-breadcrumbs-truncated-bc-settings">Settings</a><span class="breadcrumbs-separator" aria-hidden="true">/</span></li>
<li class="breadcrumbs-item"><a class="breadcrumbs-link breadcrumbs-current" href="#example-breadcrumbs-truncated-bc-appearance" aria-current="page">Appearance</a></li>
</ol>
</nav><p id="example-breadcrumbs-truncated-bc-home" tabindex="-1" class="j3w1-example-target">Example destination: bc home</p><p id="example-breadcrumbs-truncated-level-0" tabindex="-1" class="j3w1-example-target">Example destination: level 0</p><p id="example-breadcrumbs-truncated-level-1" tabindex="-1" class="j3w1-example-target">Example destination: level 1</p><p id="example-breadcrumbs-truncated-level-2" tabindex="-1" class="j3w1-example-target">Example destination: level 2</p><p id="example-breadcrumbs-truncated-bc-projects" tabindex="-1" class="j3w1-example-target">Example destination: bc projects</p><p id="example-breadcrumbs-truncated-bc-theme" tabindex="-1" class="j3w1-example-target">Example destination: bc theme</p><p id="example-breadcrumbs-truncated-bc-site" tabindex="-1" class="j3w1-example-target">Example destination: bc site</p><p id="example-breadcrumbs-truncated-bc-settings" tabindex="-1" class="j3w1-example-target">Example destination: bc settings</p><p id="example-breadcrumbs-truncated-bc-appearance" tabindex="-1" class="j3w1-example-target">Example destination: bc appearance</p></j3w1-breadcrumbs>Install and register
Use the exact version. If npm publication is pending, install the release tarball from the installation guide.
npm install --save-exact @j3w1/ui@4.0.0import '@j3w1/ui/tokens.css';
import '@j3w1/ui/styles/breadcrumbs.css';
import '@j3w1/ui/register/breadcrumbs';Insert the maintained markup above after loading these imports. Its native children provide accessible names and form behavior; the empty custom tag alone does not create a control.
Copy the complete implementation
npx --package=@j3w1/ui@4.0.0 j3w1-ui copy breadcrumbs --out ./vendor/j3w1/breadcrumbsThe CLI verifies every file before writing and refuses overwrites. Serve the output over HTTP and open index.html. Keep its modules, CSS, tokens and licence notices together.
Public API
attributes
| Name | Type / signature | Meaning |
|---|---|---|
disabled | CustomEvent | Disable the native controls owned by this instance. |
loading | CustomEvent | Mark the primary control busy and prevent duplicate activation. |
properties
| Name | Type / signature | Meaning |
|---|---|---|
disabled | boolean | Delegates disabled state to native children. |
name | string | Native control name; application form keys remain explicit. |
methods
| Name | Type / signature | Meaning |
|---|---|---|
refresh | (): void | Reconnect behavior after replacing native child structure. |
focus | (options?: FocusOptions): void | Focus the first usable native control. |
events
| Name | Type / signature | Meaning |
|---|---|---|
j3w1-toggle | CustomEvent | A collapsed breadcrumb group changed visibility. |
Dependencies and verification
Registered components: none. Style dependencies: none.
Package presence establishes an available implementation. Actual passes depend on the tested artifact and environment. Read specification execution evidence; read packed-consumer evidence; inspect the complete state matrix.
Full implementation manifest, API and token dependency closure
Canonical specification
Breadcrumbs breadcrumbs
The path from the root to the current page as an ordered list of links separated by slashes; the last item is the current page and not a link.
Report an issue with this component
Tokens
Focus a role to inspect its values; follow its link for persistent usage and source details.
| Part | Role | Value | Use |
|---|---|---|---|
root.bg | color.surface.defaultapproveduse | #0d0707 | D-041 surface.default: color.primitive.modern.panel. |
link.text | color.text.linkapproveduse | #f73f35 | Strong red link text, distinct from rose body text and headings; retain the underline. |
link.underline | color.text.link-underlineobserveduse | #dc282e | Link underline. |
link.text-hover | color.text.link-hoverobserveduse | #f4eeee | Link text on hover, over interaction.hover.bg-strong. |
link.bg-hover | color.interaction.hover.bgapproveduse | #1c1010 | D-041 interaction.hover.bg: color.primitive.modern.hover. |
link.ring | color.interaction.focus.ringobserveduse | #e53935 | 1px dashed focus ring on controls and rows. |
current.text | color.text.brightapproveduse | #ffa2a7 | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
separator.text | color.text.mutedapproveduse | #d4868b | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
ellipsis.text | color.text.defaultapproveduse | #e99499 | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
ellipsis.bg-hover | color.interaction.hover.bgapproveduse | #1c1010 | D-041 interaction.hover.bg: color.primitive.modern.hover. |
Purpose
Where the current page sits in a hierarchy, with a jump to any ancestor. Secondary navigation: never a replacement for the sidebar or page title, and omitted on the root page.
Anatomy
Parts as listed in the anatomy; the separator follows every item but the last.
States
| State | Visual | Non-colour channel |
|---|---|---|
| default | links color.text.link, 1px underline; separators color.text.muted; current color.text.bright | underline on links; none on the current page |
| hover | link → color.interaction.hover.bg, text color.text.link-hover | underline 1px → 2px; cursor |
| focus-visible | 1px dashed color.interaction.focus.ring at −2px around the link | the ring |
| current | color.text.bright; no underline; no hover | aria-current="page"; no underline |
| truncated | middle levels replaced by an … button in color.text.default | aria-expanded="false"; its label counts the hidden levels |
Keyboard
As in the key table. The ellipsis button discloses the hidden levels in place on Enter or Space; focus stays on it, so the revealed links are the next Tab stops.
Accessibility
The nav label “Breadcrumb” is translated. The aria-hidden separator keeps
“slash” unspoken; the list gives the count. aria-current="page" marks the
last item, link or not. Hidden levels stay in the DOM (hidden until
disclosed) so find-in-page reaches them. Text meets 4.5:1; underline and ring
3:1. Each link is at least 24 CSS pixels tall through line box and padding.
Portability
Plain inline links and text; the separator needs only an inline-start margin that flips in RTL. Without an underline, a toolkit draws the link in the link colour and records the deviation. The ellipsis is optional; without it the full trail shows and wraps.
Non-examples
Chevrons, arrows or bullets as separators. A trail ending with the site name
instead of the current page. The current page as an underlined link.
text-overflow truncation that hides unreachable levels. A horizontally
scrolling trail. Uppercase or letter-spaced items. Separators read aloud.
Contrast report
8 declared pairs measured on resolved sRGB values with the WCAG 2.x formula; 0 waived (decorative only), 0 failing. A pass is a design target for the named role, not an application-wide conformance claim.
| Pair | State | Kind | Foreground | Background | Ratio | Min | Result |
|---|---|---|---|---|---|---|---|
| breadcrumbs default text | default | text | color.text.link #f73f35 | color.surface.default #0d0707 | 5.44 | 4.5 | pass |
| breadcrumbs hover text | hover | text | color.text.link-hover #f4eeee | color.interaction.hover.bg #1c1010 | 16.19 | 4.5 | pass |
| breadcrumbs focus-visible text | focus-visible | text | color.text.link #f73f35 | color.surface.default #0d0707 | 5.44 | 4.5 | pass |
| breadcrumbs focus-visible outline | focus-visible | ui | color.interaction.focus.ring #e53935 | color.surface.default #0d0707 | 4.73 | 3 | pass |
| breadcrumbs current text | current | text | color.text.bright #ffa2a7 | color.surface.default #0d0707 | 10.45 | 4.5 | pass |
| breadcrumbs truncated text | truncated | text | color.text.default #e99499 | color.surface.default #0d0707 | 8.72 | 4.5 | pass |
| separator on the panel surface | — | text | color.text.muted #d4868b | color.surface.default #0d0707 | 7.22 | 4.5 | pass |
| link underline | — | ui | color.text.link-underline #dc282e | color.surface.default #0d0707 | 4.17 | 3 | pass |
Keys
| Key | Action |
|---|---|
| Tab / Shift+Tab | Moves through the links in order; the current page is skipped when it is not a link. |
| Enter | Follows the focused link, or discloses the hidden levels from the ellipsis button. |
For agents
Component JSON ·Implementation brief ·Build a task kit ·
Related: link sidebar-nav pagination tree
Stress fixtures: FX-LONG FX-320 FX-ZOOM-200 FX-I18N FX-RTL FX-RM FX-HC FX-STATE-MATRIX