Skip to main content

Breadcrumbs

A breadcrumb trail consists of a list of links to the parent pages of the current page in hierarchical order. It helps users find their place within a website or web application. Always place breadcrumbs before a page’s <main> content element. This makes sure the Skip to content link allows the user to skip all navigation, including the breadcrumbs. Where possible this should be set in the page template in pageConfig. This will ensure it will have the correct placing on the page.

Open this example in a new window
<nav class="breadcrumb" aria-label="Breadcrumb">
  <ol class="breadcrumb__items u-fs-s">
    <li class="breadcrumb__item" id="breadcrumb-1">
      <a class="breadcrumb__link" href="/">Home</a>
      <svg class="svg-icon" viewBox="0 0 7.5 12.85" xmlns="http://www.w3.org/2000/svg" focusable="false">
        <path d="M5.74,14.28l-.57-.56a.5.5,0,0,1,0-.71h0l5-5-5-5a.5.5,0,0,1,0-.71h0l.57-.56a.5.5,0,0,1,.71,0h0l5.93,5.93a.5.5,0,0,1,0,.7L6.45,14.28a.5.5,0,0,1-.71,0Z" transform="translate(-5.02 -1.59)" />
      </svg>
    </li>
    <li class="breadcrumb__item" id="breadcrumb-2">
      <a class="breadcrumb__link" href="/components">Components</a>
      <svg class="svg-icon" viewBox="0 0 7.5 12.85" xmlns="http://www.w3.org/2000/svg" focusable="false">
        <path d="M5.74,14.28l-.57-.56a.5.5,0,0,1,0-.71h0l5-5-5-5a.5.5,0,0,1,0-.71h0l.57-.56a.5.5,0,0,1,.71,0h0l5.93,5.93a.5.5,0,0,1,0,.7L6.45,14.28a.5.5,0,0,1-.71,0Z" transform="translate(-5.02 -1.59)" />
      </svg>
    </li>
  </ol>
</nav>
Nunjucks macro options
Name Type Required Description
classes string false Custom classes to add to the breadcrumb
ariaLabel string true The label added to the nav element
id string false The ID added to the nav element
itemsList Array true An array of items to show in the breadcrumb list
Name Type Required Description
itemClasses string false Custom classes to add to the breadcrumb list item
linkClasses string false Custom classes to add to the breadcrumb link
url string true The url for the link
text string true The name of the page
attributes object false HTML attributes (for example data attributes) to add to the breadcrumb element
id string false The ID added to the breadcrumb
{% from "components/breadcrumb/_macro.njk" import onsBreadcrumb %}
{{
    onsBreadcrumb({
        "ariaLabel": 'Breadcrumb',
        "itemsList": [
            {
                "url": '/',
                "text": 'Home'
            },
            {
                "url": '/components',
                "text": 'Components'
            }
        ]
    })
}}

{% from "components/icons/_macro.njk" import onsIcon %}
{% macro onsBreadcrumb(params) %}
    <nav class="breadcrumb{{ ' ' + params.classes if params.classes else '' }}" aria-label="{{ params.ariaLabel }}" {% if params.id is defined and params.id %} id="{{ params.id }}"{% endif %}>
        <ol class="breadcrumb__items u-fs-s">
            {% for item in (params.itemsList if params.itemsList is iterable else params.itemsList.items()) %}
                <li class="breadcrumb__item{{ ' ' + item.itemClasses if item.itemClasses else '' }}" id="breadcrumb-{{ loop.index }}">
                    <a class="breadcrumb__link{{ ' ' + item.linkClasses if item.linkClasses else '' }}" href="{{ item.url }}"{% if item.id is defined and item.id %} id="{{ item.id }}"{% endif %}
                    {% if item.attributes is defined and item.attributes %}{% for attribute, value in (item.attributes.items() if item.attributes is mapping and item.attributes.items else item.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
                    >{{ item.text }}</a>
                    {{
                        onsIcon({
                            "icon": "chevron"
                        })
                    }}
                </li>
            {% endfor %}
        </ol>
    </nav>
{% endmacro %}

$breadcrumb-chevron-height: 0.65rem;
.breadcrumb {
  align-items: center;
  display: flex;
  padding: 1rem 0;
  &__items {
    margin: 0;
    padding: 0;
  }
  &__item {
    display: inline-block;
    margin: 0;
    white-space: nowrap; // Stop items from wrapping, break on chevron only
    &:not(:nth-last-child(1)) {
      //small screen not last child
      display: none;
    }
    .svg-icon {
      height: $breadcrumb-chevron-height;
      margin: 0 0.2rem;
      vertical-align: middle;
      width: $breadcrumb-chevron-height;
    }
    &:nth-last-child(1) {
      // small screen last child
      direction: rtl;
      .svg-icon {
        margin-left: -0.13rem;
        transform: rotate(180deg);
      }
    }
    @include mq(s) {
      //big screen
      &:not(:nth-last-child(1)) {
        //not last child
        display: inline-block;
      }
      &:nth-last-child(1) {
        // last child
        direction: ltr;
        .svg-icon {
          display: none;
        }
      }
      &:first-child:nth-last-child(1) {
        //first and last child
        direction: rtl;
        .svg-icon {
          display: inline-block;
          vertical-align: middle;
        }
      }
      &:not(:last-child).svg-icon {
        //not last child
        margin: 0;
        /* stylelint-disable */
        // We have to override the icon settings so it renders correctly in ie11
        background-position: center center;
        vertical-align: middle;
        /* stylelint-enable */
      }
    }
  }
  &__link {
    color: $color-text;
    text-decoration: underline;
  }
}

When to use this component

Use the breadcrumbs component when you need to help users understand and move between the multiple levels of a website.

When not to use this component

Don’t use the breadcrumbs component on websites with a flat structure, or to show progress through a linear journey or transaction.

If you’re using other navigational elements on the page, such as a sidebar, consider whether your users need the additional support of breadcrumbs.

How it works

  • The set of links is structured using an ordered list to provide semantic structure
  • A nav element labeled Breadcrumb identifies the structure as a breadcrumb trail and makes it a navigation landmark so that it is easy to locate
  • To prevent screen reader announcing the visual separators between links, they are added via CSS
  • The separators are part of the visual presentation that signifies the breadcrumb trail. This is already semantically represented by the nav element with its aria-label of Breadcrumb. Therefore using a display technique that is not used by screen readers prevents redundant and potentially distracting verbosity

Variants

Single breadcrumb

When the component only has a single breadcrumb it will display like this.

Open this example in a new window
<nav class="breadcrumb" aria-label="Breadcrumb">
  <ol class="breadcrumb__items u-fs-s">
    <li class="breadcrumb__item" id="breadcrumb-1">
      <a class="breadcrumb__link" href="/">Home</a>
      <svg class="svg-icon" viewBox="0 0 7.5 12.85" xmlns="http://www.w3.org/2000/svg" focusable="false">
        <path d="M5.74,14.28l-.57-.56a.5.5,0,0,1,0-.71h0l5-5-5-5a.5.5,0,0,1,0-.71h0l.57-.56a.5.5,0,0,1,.71,0h0l5.93,5.93a.5.5,0,0,1,0,.7L6.45,14.28a.5.5,0,0,1-.71,0Z" transform="translate(-5.02 -1.59)" />
      </svg>
    </li>
  </ol>
</nav>
Nunjucks macro options
Name Type Required Description
classes string false Custom classes to add to the breadcrumb
ariaLabel string true The label added to the nav element
id string false The ID added to the nav element
itemsList Array true An array of items to show in the breadcrumb list
Name Type Required Description
itemClasses string false Custom classes to add to the breadcrumb list item
linkClasses string false Custom classes to add to the breadcrumb link
url string true The url for the link
text string true The name of the page
attributes object false HTML attributes (for example data attributes) to add to the breadcrumb element
id string false The ID added to the breadcrumb
{% from "components/breadcrumb/_macro.njk" import onsBreadcrumb %}
{{
    onsBreadcrumb({
        "ariaLabel": 'Breadcrumb',
        "itemsList": [
            {
                "url": '/',
                "text": 'Home'
            }
        ]
    })
}}

{% from "components/icons/_macro.njk" import onsIcon %}
{% macro onsBreadcrumb(params) %}
    <nav class="breadcrumb{{ ' ' + params.classes if params.classes else '' }}" aria-label="{{ params.ariaLabel }}" {% if params.id is defined and params.id %} id="{{ params.id }}"{% endif %}>
        <ol class="breadcrumb__items u-fs-s">
            {% for item in (params.itemsList if params.itemsList is iterable else params.itemsList.items()) %}
                <li class="breadcrumb__item{{ ' ' + item.itemClasses if item.itemClasses else '' }}" id="breadcrumb-{{ loop.index }}">
                    <a class="breadcrumb__link{{ ' ' + item.linkClasses if item.linkClasses else '' }}" href="{{ item.url }}"{% if item.id is defined and item.id %} id="{{ item.id }}"{% endif %}
                    {% if item.attributes is defined and item.attributes %}{% for attribute, value in (item.attributes.items() if item.attributes is mapping and item.attributes.items else item.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
                    >{{ item.text }}</a>
                    {{
                        onsIcon({
                            "icon": "chevron"
                        })
                    }}
                </li>
            {% endfor %}
        </ol>
    </nav>
{% endmacro %}

$breadcrumb-chevron-height: 0.65rem;
.breadcrumb {
  align-items: center;
  display: flex;
  padding: 1rem 0;
  &__items {
    margin: 0;
    padding: 0;
  }
  &__item {
    display: inline-block;
    margin: 0;
    white-space: nowrap; // Stop items from wrapping, break on chevron only
    &:not(:nth-last-child(1)) {
      //small screen not last child
      display: none;
    }
    .svg-icon {
      height: $breadcrumb-chevron-height;
      margin: 0 0.2rem;
      vertical-align: middle;
      width: $breadcrumb-chevron-height;
    }
    &:nth-last-child(1) {
      // small screen last child
      direction: rtl;
      .svg-icon {
        margin-left: -0.13rem;
        transform: rotate(180deg);
      }
    }
    @include mq(s) {
      //big screen
      &:not(:nth-last-child(1)) {
        //not last child
        display: inline-block;
      }
      &:nth-last-child(1) {
        // last child
        direction: ltr;
        .svg-icon {
          display: none;
        }
      }
      &:first-child:nth-last-child(1) {
        //first and last child
        direction: rtl;
        .svg-icon {
          display: inline-block;
          vertical-align: middle;
        }
      }
      &:not(:last-child).svg-icon {
        //not last child
        margin: 0;
        /* stylelint-disable */
        // We have to override the icon settings so it renders correctly in ie11
        background-position: center center;
        vertical-align: middle;
        /* stylelint-enable */
      }
    }
  }
  &__link {
    color: $color-text;
    text-decoration: underline;
  }
}

Research on this component

Based upon W3 principles

If you have conducted any user research using this component, please feed back your findings via the Design System forum

Design System forum

Discuss ‘Breadcrumbs’ on GitHub