Clean Markup

Accessible Breadcrumb Navigation with Semantic HTML and aria-current

Accessible Breadcrumb Navigation with Semantic HTML and aria-current

Breadcrumb navigation gives visitors immediate context about where they are within a multi-level site hierarchy and provides one-click shortcuts to parent categories. However, many implementations rely on generic <div> wrappers, inline <span>/</span> dividers that screen readers announce aloud on every step, and visual-only styling for the active page.

By combining a <nav aria-label="Breadcrumb"> landmark, a semantic ordered list (<ol>), CSS-generated ::before visual separators, and aria-current="page" on the final link, assistive technologies can announce the exact hierarchy depth and current location clearly.

Example

<!-- Avoid: Unlabeled divs and spoken slash characters -->
<div class="breadcrumbs">
  <a href="/">Home</a> / <a href="/articles">Articles</a> / <span>Accessibility</span>
</div>

<!-- Prefer: Labeled nav landmark, ordered list, and aria-current="page" -->
<nav aria-label="Breadcrumb">
  <ol class="breadcrumb-list">
    <li><a href="/">Home</a></li>
    <li><a href="/articles">Articles</a></li>
    <li><a href="/articles/accessibility" aria-current="page">Accessibility</a></li>
  </ol>
</nav>

Input : Hierarchical page path (Home > Articles > Accessibility)
Output : Semantic <nav> landmark with an ordered list and decorative CSS separators.

Implementation

<nav class="breadcrumb" aria-label="Breadcrumb">
  <ol class="breadcrumb__list">
    <li class="breadcrumb__item">
      <a class="breadcrumb__link" href="/">Home</a>
    </li>
    <li class="breadcrumb__item">
      <a class="breadcrumb__link" href="/guides">Frontend Guides</a>
    </li>
    <li class="breadcrumb__item">
      <a class="breadcrumb__link" href="/guides/semantic-html">Semantic HTML</a>
    </li>
    <li class="breadcrumb__item">
      <a
        class="breadcrumb__link"
        href="/guides/semantic-html/breadcrumbs"
        aria-current="page"
      >
        Accessible Breadcrumbs
      </a>
    </li>
  </ol>
</nav>
.breadcrumb {
  padding: 12px 16px;
  background-color: #f6f8fa;
  border-radius: 4px;
}

.breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}

.breadcrumb__item {
  display: flex;
  align-items: center;
  font-size: 14px;
}

/* Visual divider rendered via CSS so it does not clutter DOM text */
.breadcrumb__item + .breadcrumb__item::before {
  content: "/";
  margin: 0 10px;
  color: #6a737d;
}

.breadcrumb__link {
  color: #0366d6;
  text-decoration: none;
}

.breadcrumb__link:hover,
.breadcrumb__link:focus {
  text-decoration: underline;
}

/* Style the current page directly through its semantic ARIA attribute */
.breadcrumb__link[aria-current="page"] {
  color: #24292e;
  font-weight: 600;
  text-decoration: none;
  pointer-events: none;
}

Main Point: Always use an <ol> inside <nav aria-label="Breadcrumb"> because breadcrumb trails represent a sequential hierarchy, and target [aria-current="page"] in CSS so visual styling stays synchronized with accessibility semantics.

Credits

Photo by Marvin Meyer

← Home