Exploring Markup for Breadcrumbs

Avatar of Chris Coyier
Chris Coyier on (Updated on )

In the comments for my recent post about CSS Triangle Breadcrumbs, the HTML markup I used to create them was (in essence):

<ul class="breadcrumb">
  <li><a href="#">Top Level</a></li>
  <li><a href="#">Second Level</a></li>
  <li><a href="#">Third Level</a></li>
  <li>Current Item</li>
</ul>

To which Geert van der Heide commented:

… the HTML is not semantic. Coding a breadcrumb as an unordered list makes it seem like the items are on the same hierarchical level, like it’s a set of items in a row. The items in a breadcrumb are not, they represent a path, with each link being a “child” of the last.

I thought it was a good point. An unordered list, semantically, does feel wrong. Like Geert said, it puts them all on the same hierarchical level. To get each menu item clearly onto its own level, markup like this would be required:

<ul class="breadcrumb">
    <li>
      <a href="#">Top Level</a>
      <ul>
        <li>
          <a href="#">Second Level</a>
          <ul>
             <li>
               <a href="#">Third Level</a>
               <ul>
                  <li>
                     Current Item
                 </li>
               </ul>
            </li>
         </ul>
       </li>
     </ul>
  </li>
</ul>

That’s feels pretty overwhelming though doesn’t it? I can’t see that being used, even though technically you could and get it styled just about any way you need it.

No, the “unordered” part of an unordered list is more the problem. Perhaps we could just make it an ordered list instead:

<ol class="breadcrumb">
  <li><a href="#">Top Level</a></li>
  <li><a href="#">Second Level</a></li>
  <li><a href="#">Third Level</a></li>
  <li>Current Item</li>
</ol>

That definitely feels better. Breadcrumbs are in a very specific order and so using an “ordered” list seems appropriate. I’m somehow not totally satisfied by that though. Just because a list is 1, 2, 3, etc, doesn’t really represent layers of hierarchy.

Several folks also mentioned just using links and some kind of textual visual separator.

<p class="breadcrumb">
  <a href="#">Top Level</a> >
  <a href="#">Second Level</a> >
  <a href="#">Third Level</a> >
  Current Item
</p>

Without any CSS styling at all, this is probably the most effective. The > symbol separator indicates hierarchy pretty well. Using inline elements gives the breadcrumbs a horizontal layout like breadcrumbs typically have. Again though, this isn’t terribly satisfying as the markup itself doesn’t describe what it holds very meaningfully.

I thought I’d go check out if Google had any advice on this subject. After all, Google features breadcrumbs in their search results:

Unsurprisingly, the markup of their actual search results is just a silly mess (the markup of Google-anything is a silly mess). They do, however, have something to say about how we should markup our breadcrumbs. They recommend HTML5 Microdata, and offer this example:

<div itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
  <a href="http://www.example.com/books" itemprop="url">
    <span itemprop="title">Books</span>
  </a> ›
  <div itemprop="child" itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
    <a href="http://www.example.com/books/authors" itemprop="url">
      <span itemprop="title">Authors</span>
    </a> ›
    <div itemprop="child" itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
      <a href="http://www.example.com/books/authors/stephenking" itemprop="url">
        <span itemprop="title">Stephen King</span>
      </a>
    </div>
  </div>
</div>

Looks clumsy at first glance, but actually microdata is intended for just such purposes. I’d probably go with spans here, instead of the div wrappers regardless.

I’m not sure how microdata and microformats relate to one another, but it seems like microformats suggests just giving the wrapper a class name of ‘breadcrumb’ and calling it a day.

HTML5 has a bit more to say on the subject (see update below) Using the “up” value in a rel attribute signifies that element is part of a hierarchical structure and also indicates the distance from the current document to the reference document.

<nav>
 <p>
  <a href="/" rel="index up up up">Main</a> >
  <a href="/products/" rel="up up">Products</a> >
  <a href="/products/dishwashers/" rel="up">Dishwashers</a> >
  <a>Second hand</a>
 </p>
</nav>

The nav tag is especially appropriate, and any of the code examples above would benefit semantically from being wrapped in it. Aside from that, this may be the most satisfying of all the examples to me as it semantically describes the nature of a breadcrumb. The rel tag is specifically for describing relationships between elements, so that is a fit. Also visually, without any styling, the breadcrumb look is accomplished.

But please note: the rel/up thing is not final and isn’t likely to last. There is an open issue which indicates using multiple “up”s isn’t a very clean way to do things and suggestions for values like “up2”, “great-grandparent” or even a new attribute like level="3" are going around.

Update: Nelson Menezes wrote in to let me know HTML5 and rel="up" is dead. References: 1 2

So where are we at on this? I’d say that there is no super-ultimate best-possible-way to handle breadcrumb markup yet. Hopefully obviously, this really isn’t a big deal. Just pick one that works for you and go with it. I just think it’s interesting territory for an HTML conversation. If you have any ideas for breadcrumb markup not shown here, please share!