Breadcrumbs

Material Design 3 breadcrumbs component for navigation hierarchy

Breadcrumbs

Breadcrumbs show the current location within a navigational hierarchy. They help users understand where they are and provide quick access to parent pages.

Basic Usage

Basic Breadcrumbs

Separator Variants

Choose from different separator styles to match your design:

Slash Separator (Default)

Slash Separator

Chevron Separator

Chevron Separator

Dot Separator

Dot Separator

Arrow Separator

Arrow Separator

Add icons to breadcrumb items for better visual clarity:

Breadcrumbs with Icons

Home Icon Only

A common pattern uses just an icon for the home link to save space:

Home Icon Only

Color Variants

Use color variants to highlight active breadcrumbs:

Primary

Primary Color

Secondary

Secondary Color

Tertiary

Tertiary Color

Size Variants

Adjust breadcrumb sizes for different layouts:

Small

Small Size

Default

Default Size

Large

Large Size

Contained Variant

Add background container for emphasis:

Contained Breadcrumbs

No Wrap Variant

Prevent wrapping for horizontal scrolling:

No Wrap Breadcrumbs

Collapsed Breadcrumbs (with Ellipsis)

For long navigation paths, use ellipsis to show only key items:

Collapsed Breadcrumbs

Disabled State

Mark breadcrumb items as disabled:

Disabled Breadcrumb Item

Best Practices

Hierarchy Representation

Use breadcrumbs to show the hierarchical structure of your site:

Hierarchy Representation

Maximum Items

For deep hierarchies, collapse middle items:

Maximum Items with Ellipsis

Accessibility

  • Use semantic <nav> element with aria-label
  • Provide meaningful link text
  • Mark current page as aria-current="page"
  • Ensure sufficient color contrast

Accessible Breadcrumbs

Mobile Considerations

Use smaller sizes and no-wrap variant for mobile:

Mobile-Optimized Breadcrumbs

Framework Examples

React

interface BreadcrumbItem {
  label: string;
  href?: string;
  icon?: React.ReactNode;
}

interface BreadcrumbsProps {
  items: BreadcrumbItem[];
  separator?: 'slash' | 'chevron' | 'dot' | 'arrow';
  size?: 'sm' | 'md' | 'lg';
  color?: 'primary' | 'secondary' | 'tertiary';
  contained?: boolean;
  maxItems?: number;
}

export function Breadcrumbs({
  items,
  separator = 'slash',
  size,
  color,
  contained = false,
  maxItems
}: BreadcrumbsProps) {
  const displayItems = maxItems && items.length > maxItems
    ? [...items.slice(0, 1), { label: '...', collapsed: true }, ...items.slice(-2)]
    : items;

  const classes = [
    'breadcrumbs',
    `breadcrumbs-${separator}`,
    size && `breadcrumbs-${size}`,
    color && `breadcrumbs-${color}`,
    contained && 'breadcrumbs-contained'
  ].filter(Boolean).join(' ');

  return (
    <nav className={classes} aria-label="Breadcrumb navigation">
      {displayItems.map((item, index) => (
        <React.Fragment key={index}>
          {item.collapsed ? (
            <button className="breadcrumb-ellipsis" aria-label="Show more breadcrumbs" />
          ) : item.href ? (
            <a href={item.href} className="breadcrumb-link">
              {item.icon}
              {item.label}
            </a>
          ) : (
            <span className="breadcrumb-item breadcrumb-item-active" aria-current="page">
              {item.icon}
              {item.label}
            </span>
          )}
          {index < displayItems.length - 1 && (
            <span className="breadcrumb-separator" aria-hidden="true"></span>
          )}
        </React.Fragment>
      ))}
    </nav>
  );
}

// Usage
<Breadcrumbs
  items={[
    { label: 'Home', href: '/' },
    { label: 'Docs', href: '/docs' },
    { label: 'Components' }
  ]}
  separator="chevron"
  color="primary"
/>

Vue

<template>
  <nav :class="classes" aria-label="Breadcrumb navigation">
    <template v-for="(item, index) in displayItems" :key="index">
      <button
        v-if="item.collapsed"
        class="breadcrumb-ellipsis"
        aria-label="Show more breadcrumbs"
        @click="expandAll"
      />
      <a
        v-else-if="item.href"
        :href="item.href"
        class="breadcrumb-link"
      >
        <component v-if="item.icon" :is="item.icon" class="breadcrumb-icon" />
        {{ item.label }}
      </a>
      <span
        v-else
        class="breadcrumb-item breadcrumb-item-active"
        aria-current="page"
      >
        <component v-if="item.icon" :is="item.icon" class="breadcrumb-icon" />
        {{ item.label }}
      </span>
      <span
        v-if="index < displayItems.length - 1"
        class="breadcrumb-separator"
        aria-hidden="true"
      />
    </template>
  </nav>
</template>

<script setup>
import { computed, ref } from 'vue'

const props = defineProps({
  items: {
    type: Array,
    required: true
  },
  separator: {
    type: String,
    default: 'slash',
    validator: (value) => ['slash', 'chevron', 'dot', 'arrow'].includes(value)
  },
  size: {
    type: String,
    validator: (value) => ['sm', 'md', 'lg'].includes(value)
  },
  color: {
    type: String,
    validator: (value) => ['primary', 'secondary', 'tertiary'].includes(value)
  },
  contained: {
    type: Boolean,
    default: false
  },
  maxItems: Number
})

const expanded = ref(false)

const displayItems = computed(() => {
  if (!props.maxItems || props.items.length <= props.maxItems || expanded.value) {
    return props.items
  }
  return [
    props.items[0],
    { label: '...', collapsed: true },
    ...props.items.slice(-2)
  ]
})

const classes = computed(() => {
  return [
    'breadcrumbs',
    `breadcrumbs-${props.separator}`,
    props.size && `breadcrumbs-${props.size}`,
    props.color && `breadcrumbs-${props.color}`,
    props.contained && 'breadcrumbs-contained'
  ].filter(Boolean).join(' ')
})

const expandAll = () => {
  expanded.value = true
}
</script>

<!-- Usage -->
<Breadcrumbs
  :items="[
    { label: 'Home', href: '/' },
    { label: 'Docs', href: '/docs' },
    { label: 'Components' }
  ]"
  separator="chevron"
  color="primary"
  :max-items="3"
/>

API Reference

Class Names

ClassDescription
.breadcrumbsBase breadcrumbs container (required)
.breadcrumb-itemIndividual breadcrumb item
.breadcrumb-linkClickable breadcrumb link
.breadcrumb-item-activeCurrent/active breadcrumb item
.breadcrumb-separatorSeparator between items
.breadcrumb-iconIcon within breadcrumb item
.breadcrumb-ellipsisCollapsed items button
.breadcrumb-item-disabledDisabled breadcrumb item

Separator Variants

ClassDescription
.breadcrumbs-slashSlash separator (/)
.breadcrumbs-chevronChevron separator (›)
.breadcrumbs-dotDot separator (•)
.breadcrumbs-arrowArrow separator (→)

Color Variants

ClassDescription
.breadcrumbs-primaryPrimary color for hover/active
.breadcrumbs-secondarySecondary color for hover/active
.breadcrumbs-tertiaryTertiary color for hover/active

Size Variants

ClassDescription
.breadcrumbs-smSmall breadcrumbs (0.813rem)
.breadcrumbs-mdDefault breadcrumbs (0.875rem)
.breadcrumbs-lgLarge breadcrumbs (1rem)

Layout Variants

ClassDescription
.breadcrumbs-containedBreadcrumbs with background container
.breadcrumbs-nowrapPrevent wrapping, enable horizontal scroll

Combinations

Contained with Chevron and Primary Color

Large with Arrow and No Wrap

See Also