Accessibility pattern · Navigation

Breadcrumb

A labelled nav holds an ordered list of links; the last one is the current page and says so with aria-current. The separators are drawn in CSS, so screen readers never read out a row of arrows, and on a narrow screen the middle levels fold behind a button.

WCAG criteria
6
Keyboard rules
3
Checked with
axe, keyboard and the inspector

Live demo

Try it

Use it with a mouse, a keyboard or a screen reader. The inspector beside it shows what the browser tells assistive technology as you go: focus, state changes and announcements.

Kanjivaram silk saree

Handwoven in Kanchipuram, in temple red with a gold zari border.

₹18,500

The demo works without JavaScript only as far as its HTML does; the inspector needs JavaScript.

Keyboard

Keys it answers to

Every action works without a pointer.

KeyWhat it does
Tab or ShiftTabMoves along the trail from link to link. On a narrow screen it stops on the fold button between the first level and the last two.
EnterFollows the focused link.
Enter or SpaceOn the fold button, shows or hides the middle levels. Focus stays on the button, and the next Tab reaches the first level it revealed.

Screen readers

What it announces

Written from the roles, names and states in the markup.

WhenExpected announcement
Tab reaches the first linkStore breadcrumb, navigation. List, 6 items. Home, link
Tab reaches the last linkKanjivaram silk saree, current page, link
Tab reaches the fold button on a phoneFull path, button, collapsed
Enter shows the middle levelsExpanded

These are expected announcements, not recordings. Wording and order differ between screen readers and browsers.

Code

Copy the code

The exact files this demo runs on. The styles are served with a prefix that keeps this site's own styles out of the demo; what you copy is the original.

The markup

<div class="ap-breadcrumb" data-ap-breadcrumb>
  <nav class="ap-breadcrumb__nav" aria-label="Store breadcrumb">
    <ol class="ap-breadcrumb__list" id="bc-list">
      <li class="ap-breadcrumb__item">
        <a class="ap-breadcrumb__link" href="#bc-home">
          <svg class="ap-breadcrumb__home" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M4 10.5 12 4l8 6.5V19a1 1 0 0 1-1 1h-4.5v-5.5h-5V20H5a1 1 0 0 1-1-1Z"/></svg>
          Home
        </a>
      </li>
      <li class="ap-breadcrumb__item ap-breadcrumb__item--more">
        <button type="button" class="ap-breadcrumb__more" aria-expanded="false" aria-controls="bc-list" aria-label="Full path">
          <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><circle cx="6" cy="12" r="1.6"/><circle cx="12" cy="12" r="1.6"/><circle cx="18" cy="12" r="1.6"/></svg>
        </button>
      </li>
      <li class="ap-breadcrumb__item ap-breadcrumb__item--fold"><a class="ap-breadcrumb__link" href="#bc-women">Women</a></li>
      <li class="ap-breadcrumb__item ap-breadcrumb__item--fold"><a class="ap-breadcrumb__link" href="#bc-ethnic">Ethnic wear</a></li>
      <li class="ap-breadcrumb__item ap-breadcrumb__item--fold"><a class="ap-breadcrumb__link" href="#bc-sarees">Sarees</a></li>
      <li class="ap-breadcrumb__item"><a class="ap-breadcrumb__link" href="#bc-silk">Silk sarees</a></li>
      <li class="ap-breadcrumb__item"><a class="ap-breadcrumb__link" href="#bc-kanjivaram" aria-current="page">Kanjivaram silk saree</a></li>
    </ol>
  </nav>

  <div class="ap-breadcrumb__product">
    <span class="ap-breadcrumb__swatch" aria-hidden="true"></span>
    <div class="ap-breadcrumb__info">
      <h3 class="ap-breadcrumb__name">Kanjivaram silk saree</h3>
      <p class="ap-breadcrumb__desc">Handwoven in Kanchipuram, in temple red with a gold zari border.</p>
      <p class="ap-breadcrumb__price">₹18,500</p>
    </div>
  </div>
</div>

WCAG 2.2

What it meets

The success criteria this pattern takes care of, and how.

  • 1.3.1 Info and Relationships Level A

    An ordered list inside a labelled nav exposes the trail's order and length; the separators are CSS, not text, so they are not read as content.

  • 1.4.1 Use of Color Level A

    Links are underlined and the current page is set in heavier text without one, so neither is told apart by color alone.

  • 1.4.10 Reflow Level AA

    On a narrow screen the middle levels fold behind a button instead of the trail running off the edge or scrolling sideways.

  • 2.4.7 Focus Visible Level AA

    Every link and the fold button show a two-pixel focus ring.

  • 2.4.8 Location Level AAA

    The trail shows where the page sits in the site, and aria-current marks the page itself.

  • 4.1.2 Name, Role, Value Level A

    aria-current="page" names the current item, and the fold button exposes its name and aria-expanded state.

Usage

When to use it

Use it

  • Sites with three or more levels, like a shop's categories or a documentation tree.
  • Pages people land on from search, who need to see where they are and move up a level.

Use something else

  • Flat sites with one or two levels: the main navigation already shows where you are.
  • A record of the pages someone visited: that is history, and the Back button already keeps it.

Common failures

How it usually goes wrong

  • Separators typed as text

    Characters like › or / between links are read out at every step, as "greater than" or "slash". Here they are drawn in CSS and never announced.

  • No sign of the current page

    Without aria-current the last item sounds like any other link. With it, screen readers add "current page".

  • An unlabelled nav

    Pages often have several navigation landmarks. One announced only as "navigation" cannot be told apart from the rest.

  • Levels cut off with no way back

    Trimming the trail with an ellipsis in CSS hides levels from everyone. The fold button here brings them back on request.

  • A trail that scrolls sideways

    On a phone a long trail runs off the edge and forces sideways scrolling. Folding the middle keeps it within one or two lines.

Notes

Building it

  • Name it with aria-label="Breadcrumb". The demo says "Store breadcrumb" because this page already has a navigation called Breadcrumb at the top, and two landmarks with one name cannot be told apart.
  • The fold is a container query, so the trail folds when its own box is narrow, wherever it sits, not only when the window is.
  • Without the script the fold button stays hidden and every level shows, so nothing is lost if JavaScript fails.
  • The current page can be a link with aria-current or plain text. The WAI-ARIA example uses a link; either works as long as it is marked.

Sources: WAI-ARIA Authoring Practices: Breadcrumb

Checked with axe in light and dark themes, at desktop and phone widths, and by keyboard. Not yet tested with every screen reader and browser pair. Report a correction