Navigation

v0.0.4
Navigation

Breadcrumb

The path to the current page as a list of links.

On this page

A breadcrumb shows where the current page sits and gives a way back up. It is an ordered list of links inside a <nav>: quiet ink for the way back, strong ink for where you are, and a small chevron the stylesheet draws between steps.

Breadcrumb

<nav aria-label="Breadcrumb">  <ol class="breadcrumb">    <li class="breadcrumb-item">      <a class="breadcrumb-link" href="#projects">Projects</a>    </li>    <li class="breadcrumb-item">      <a class="breadcrumb-link" href="#atlas">Atlas</a>    </li>    <li class="breadcrumb-item">      <a class="breadcrumb-link" href="#deployments" aria-current="page">Deployments</a>    </li>  </ol></nav>

#Long paths

Steps wrap onto a second line when the row runs out, and a single long name ends in an ellipsis at 16rem. To shorten a deep path, replace the middle steps with a menu.

Long paths

<nav aria-label="Breadcrumb">  <ol class="breadcrumb">    <li class="breadcrumb-item">      <a class="breadcrumb-link" href="#home">Home</a>    </li>    <li class="breadcrumb-item">      <button type="button" class="btn btn-quiet btn-square btn-sm" popovertarget="crumbs" aria-label="Show 2 more levels">        <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">          <circle cx="5" cy="12" r="1" />          <circle cx="12" cy="12" r="1" />          <circle cx="19" cy="12" r="1" />        </svg>      </button>      <div id="crumbs" popover class="menu">        <a class="menu-item" href="#workspace">Workspace</a>        <a class="menu-item" href="#projects">Projects</a>      </div>    </li>    <li class="breadcrumb-item">      <a class="breadcrumb-link" href="#atlas">Atlas</a>    </li>    <li class="breadcrumb-item">      <a class="breadcrumb-link" href="#settings" aria-current="page">Environment variables and secrets</a>    </li>  </ol></nav>

#Accessibility

  • Wrap the list in <nav aria-label="Breadcrumb"> and use an <ol>: the order is the meaning.
  • Mark the last step with aria-current="page". It may stay a link to the current page or be an <a> without href.
  • The chevrons are drawn by the stylesheet and are not announced. They mirror in right-to-left text.

#Classes

ClassDescription
breadcrumbThe list of steps, on an ol inside a nav with aria-label. Steps wrap onto a second line when the row runs out
breadcrumb-itemA step, on an li. The stylesheet draws a chevron before every step but the first and mirrors it in right-to-left text
breadcrumb-linkThe link of a step. A long name ends in an ellipsis at 16rem

#Source

@master/ui/components/breadcrumb.css
/* * Breadcrumb: the path to the current page, as an ordered list of links inside a <nav>. * Quiet ink for the way back, strong ink for where you are, and a small chevron between steps. */@layer components {  .breadcrumb {    display: flex;    flex-wrap: wrap;    align-items: center;    gap: .25rem .375rem;    min-width: 0;    margin: 0;    padding: 0;    color: var(--color-text-muted);    font-size: .8125rem;    line-height: 1.4;    list-style: none;  }  .breadcrumb-item {    display: inline-flex;    align-items: center;    gap: .375rem;    min-width: 0;    &:not(:first-child)::before {      content: '';      flex: none;      width: .875rem;      height: .875rem;      background: var(--color-text-disabled);      mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6.5 4.5 3.5 3.5-3.5 3.5'/%3E%3C/svg%3E") center / contain no-repeat;    }    &:dir(rtl)::before {      scale: -1 1;    }    @media (forced-colors: active) {      &::before {        background: CanvasText;      }    }  }  /* A step: a link, or the current page with aria-current="page". Long names end in an ellipsis. */  .breadcrumb-link {    max-width: 16rem;    border-radius: calc((var(--radius-chip) - 2px) * var(--corner-scale));    corner-shape: var(--corner-shape);    overflow: hidden;    color: inherit;    text-decoration: none;    text-overflow: ellipsis;    white-space: nowrap;    transition: color var(--duration-quick) var(--easing-glide);    @media (hover: hover) {      &:hover {        color: var(--color-text-strong);      }    }    /* Pressed: the strong ink, as under the pointer, so a tap is answered too. */    &:active {      color: var(--color-text-strong);    }    &[aria-current="page"] {      color: var(--color-text-strong);    }    &:focus-visible {      @apply --focus-ring;    }  }}