You are looking at archived content. The hot new stuff is happening at Veerle's blog 3.0. You should check it out!

Feb 10

Simple scalable CSS based breadcrumbs

2009 at 03.42 pm posted by Veerle Pieters

A few days ago I was implementing breadcrumbs in a website I’m working on. Not that I sincerely believe every site needs this, but on some occasions and to some users breadcrumbs are practical. Anyhow, it gave me the idea to write an article about it because it’s been a while since I last wrote about anything CSS-related. The one I’ll share with you is a very simple one. It uses only one simple graphic. The rest is basic CSS styling with an unordered list as HTML code.

A simple scalable CSS based breadcrumbs

The one I implemented in the project I'm working on looks a bit similar, but was more complex to code. More CSS classes and a span element were needed to make it work. I thought I stick to a very simple one, a bit like the one Apple is using.

The HTML code

Here is our HTML code. It's a simple unordered list:

  1. <ul id="crumbs">
  2. <li><a href="#">Home</a></li>
  3. <li><a href="#">Main section</a></li>
  4. <li><a href="#">Sub section</a></li>
  5. <li><a href="#">Sub sub section</a></li>
  6. <li>The page you are on right now</li>
  7. </ul>

All items have links, except the page you're on. While working on this, I wondered if a list is the most 'appropriate' structured code to use for breadcrumbs. I don't think there is a strict rule here, but I believe using a list is a meaningful way and so semantically I believe it's appropriate.

The CSS

Here is the CSS styling:

  1. ul, li {
  2. list-style-type:none;
  3. padding:0;
  4. margin:0;
  5. }

First we reset the basic list styling behavior: hide the typical round bullets that appear by default and remove the indentation by setting the margin and padding to zero.

  1. #crumbs {
  2. border:1px solid #dedede;
  3. height:2.3em;
  4. }

I've given the list an ID called #crumbs. I've add a border around the breadcrumbs and set a specific height.

  1. #crumbs li {
  2. float:left;
  3. line-height:2.3em;
  4. padding-left:.75em;
  5. color:#777;
  6. }

All crumbs need to appear on 1 horizontal line so we give each li element float:left. The text needs to be center aligned vertically, so we use the same value for line-height as we did for the height of the list which is 2.3em. To leave some space to the left in between each crumb we add a padding on the left of 0.75 ems. Next, we add the color of the text.

  1. #crumbs li a {
  2. display:block;
  3. padding:0 15px 0 0;
  4. background:url(images/crumbs.gif) no-repeat right center;
  5. }

We want to have the entire arrow area clickble. To do this we give the a element display:block. We add the background image to the a element. The image looks like this:

Breadcrumb image

It is a rather big image, but that's because we want it to be scalable. The background image is positioned to the right and vertically centered. So when the user enlarges the text in his browser the corner of the arrow will always stay nicely vertically center aligned.

  1. #crumbs li a:link, #crumbs li a:visited {
  2. text-decoration:none;
  3. color:#777;
  4. }

Add the styling for the text links. I've used text-decoration:none to hide the underlining and I've used a soft color just to to draw not too much attention to these.

  1. #crumbs li a:hover, #crumbs li a:focus {
  2. color:#dd2c0d;
  3. }

Then last but not least add the text styling when the user hovers the crumbs. If you want to have the underlining appear again on hover, just add text-decoration:underline.

Final result


56served

gravatar

1

permalink this comment Richard Tue Feb 10, 2009 at 04.24 pm

As always your examples are great. This is such a clean implementation of a breadcrumb trail. The code and the visual side of it.

Thank you!


gravatar

2

permalink this comment Nokadota Tue Feb 10, 2009 at 04.36 pm

I think I’ll implement this into some future website templates. Thanks for the simple and helpful tutorial Veerle.


gravatar

3

permalink this comment Maarten Tue Feb 10, 2009 at 04.43 pm

On breadcrumb semantics, the SimpleQuiz had a chapter about breadcrumbs.


gravatar

4

permalink this comment Marco Tue Feb 10, 2009 at 04.45 pm

Well done Veerle, looks pretty nice! Reminds me of the Apple-like breadcrumb CSS menu explained by Janko.

Keep up the good work!


gravatar

5

permalink this comment Soh Tanaka Tue Feb 10, 2009 at 05.01 pm

That is pretty cool :-)


gravatar

6

permalink this comment David Tue Feb 10, 2009 at 05.10 pm

I really like the idea of using a big image that scales up.

Does anyone know what browsers increase text but not images? (good for this) And what just zoom everything? (still pixellates the image)

I “think” Safari increases just text while FF and IE zoom everything as default behaviour on Windows.


gravatar

7

permalink this comment Filip Salomonsson Tue Feb 10, 2009 at 05.19 pm

Beautiful.

If you set padding-right on the a element value in ems instead of pixels, it’ll retain it’s dignity even at HUGE text sizes.


gravatar

8

permalink this comment schahryar Tue Feb 10, 2009 at 05.21 pm

Very useful, thanks :)


gravatar

9

permalink this comment Art Lawry Tue Feb 10, 2009 at 05.22 pm

Try doing this:

1) Move the left padding from the li to the a.
2) Add a left margin to the a of -.075em

This ought to fix the display issue with the first breadcrumb (Home) where its background suddenly changes from gray gradient to white just to the left of the text.

Way to make this solution scalable with text size :)


gravatar

10

permalink this comment Erik Vorhes Tue Feb 10, 2009 at 05.27 pm

Thanks!

One suggestion: since the breadcrumb essentially displays a kind of hierarchy, it might make some sense to use an ordered list instead of an unordered list. (But it’s hardly something to obsess over.)


gravatar

11

permalink this comment Art Lawry Tue Feb 10, 2009 at 05.37 pm

Hi Erik,

Along the same lines, would nested uls with one li per level be more appropriate as it represents hierarchy while lis of the same ul represent equality?


gravatar

12

permalink this comment Jeremy Latham Tue Feb 10, 2009 at 05.38 pm

I was about to post the same comment as Erik, then I saw his.

An ol would seem more appropriate based on the hierarchical nature of a breadcrumb trail. But I’ve never implemented a breadcrumb list before - so you’re one ahead of me.

Thanks for your HUGE contributions to the community! You do amazing work.


gravatar

13

permalink this comment Tom van Hoogstraten Tue Feb 10, 2009 at 05.45 pm

Very nice! Thank you very much.


gravatar

14

permalink this comment Arie Zonshine Tue Feb 10, 2009 at 05.47 pm

Excellent article, thanks a lot!
Can’t wait for the first opportunity to implement it…


gravatar

15

permalink this comment Mike D. Tue Feb 10, 2009 at 05.57 pm

Very nice.  I almost wonder if maybe a nested list is the most semantic, since each sub-item is a child of its parent. The HTML wouldn’t be much bigger, with just the addition of ULs around each LI.  Anyway, just a thought.  Looks great!


gravatar

16

permalink this comment maweki Tue Feb 10, 2009 at 06.49 pm

In the WCAG2.0 there’s a Part about breadcrumb trails and they suggest (as I understand it) not using complex but a rather simple markup:

http://www.w3.org/TR/2008/NOTE-WCAG20-TECHS-20081211/G65

I don’t know which one would be more appropriate but I guess in text- and audiobrowsers a list-style Breadcrumb trail uses too much time/space.

But that’s just guesswork.


gravatar

17

permalink this comment Sam Tue Feb 10, 2009 at 07.22 pm

Another vote for using an ordered list.

And while nested lists might be the most semantically correct, they would involve an unnecessary amount of markup.


gravatar

18

permalink this comment Chiara Tue Feb 10, 2009 at 07.33 pm

This works great in a perfect world, where your clients do not have pages with long, long titles… And when the breadcrumb is too long to stay in a single line it crashes…

But anyway, I always appreciate your work ! :)


gravatar

19

permalink this comment Veerle Pieters Tue Feb 10, 2009 at 07.41 pm

Thank you everyone :)

Art Lawry said:

1) Move the left padding from the li to the a. 2) Add a left margin to the a of -.075em. This ought to fix the display issue with the first breadcrumb (Home) where its background suddenly changes from gray gradient to white just to the left of the text.

Oh, I actually didn’t notice this until you mentioned this here. Thank you for the tip ;)

Erik Vorhes said:

One suggestion: since the breadcrumb essentially displays a kind of hierarchy, it might make some sense to use an ordered list instead of an unordered list. (But it’s hardly something to obsess over.)

I thought about using an ordered list too, but then I thought would that make ‘more’ sense? Also, if you start thinking about it, you would actually need to code a nested list, because then you get the right hierarchy, but wouldn’t that be a bit over the top?

Art Lawry said:

Hi Erik, Along the same lines, would nested uls with one li per level be more appropriate as it represents hierarchy while lis of the same ul represent equality?

Yes exactly my thinking too. I see some other people think the same as well. Not sure if I would go that far though :)

maweki said:

In the WCAG2.0 there’s a Part about breadcrumb trails and they suggest (as I understand it) not using complex but a rather simple markup. I don’t know which one would be more appropriate but I guess in text- and audiobrowsers a list-style Breadcrumb trail uses too much time/space.

Thank you for the info. I guess you could use 1 div for the breadcrumb and spans around each crumb (to add styling), then maybe hide the separator via CSS? Not sure, I just like more graphical styling instead of having it appear as pure text.

Chiara said:

This works great in a perfect world, where your clients do not have pages with long, long titles… And when the breadcrumb is too long to stay in a single line it crashes…

That’s why I said in the beginning that some sites needed and others don’t :) I see breadcrumbs as a last resort and will try to tackle the root of problem first before using them. However in some cases the client insist on using them and than it is a matter of watching the users to see if they really improve things. When it is really long you can also just resort to a simple ... ;)


gravatar

20

permalink this comment Filip Salomonsson Tue Feb 10, 2009 at 07.52 pm

I guess you could use 1 div for the breadcrumb and spans around each crumb (to add styling), then maybe hide the separator via CSS?

I like that approach. But would you even need spans? A p or div with as looks like it would work, with a span only for “the page you are on”.

(I only did a Q&D test with firebug, though, so don’t take my word for it)


gravatar

21

permalink this comment Lieven Tue Feb 10, 2009 at 07.56 pm

Not sure, I just like more graphical styling instead of having it appear as pure text.

It’s better this way, when CSS turned off it’s still ledgible.


gravatar

22

permalink this comment Veerle Pieters Tue Feb 10, 2009 at 08.10 pm

Lieven said:

It’s better this way, when CSS turned off it’s still ledgible.

Not sure if I follow you here, a list is still legible imho. If you think otherwise than all navigation on most sites isn’t.


gravatar

23

permalink this comment Lieven Tue Feb 10, 2009 at 08.20 pm

I meant that a list is better, when the CSS is turned off , then a div. There is more coherence. When div’s are used the “breadcrumb” falls apart, codewise.

I thought you wanted to replace the li with a div… or isn’t that correct?


gravatar

24

permalink this comment Veerle Pieters Tue Feb 10, 2009 at 08.30 pm

Lieven said:

I thought you wanted to replace the li with a div… or isn’t that correct?

Yes because the WCAG 2.0 recommends keeping it simple (see comment) , so not using a list. That’s why I said I would resort to a div (for a more graphical look) in combination with spans and hiding the > via CSS. So it still would make sense even with the CSS off. WCAG is the source for accessibility so that’s why I was thinking along those lines :)


gravatar

25

permalink this comment Patternhead Tue Feb 10, 2009 at 11.07 pm

Great article. I’ve been playing around with somethig similar but I’m using a CSS sprite so that the background image changes slightly on hover. Seems to work pretty well.


gravatar

26

permalink this comment Vladimir Tue Feb 10, 2009 at 11.23 pm

Lovely tutorial! Clean and simple.


gravatar

27

permalink this comment kzutter Wed Feb 11, 2009 at 12.47 am

Thanks for breaking into small comprehensible steps. Reminds me that the CSS elephant is much easier to eat one bite at a time.


gravatar

28

permalink this comment Matt Claypotch Wed Feb 11, 2009 at 08.02 am

That is a hella clever technique to get the gradient and scaling. Thanks so much for sharing this!


gravatar

29

permalink this comment Jed Wed Feb 11, 2009 at 09.21 am

Great article. It’s exactly what I’ve been looking for. Thanks a lot!


gravatar

30

permalink this comment Jan Verhulst Wed Feb 11, 2009 at 09.45 am

Very nice tutorial, this will surely come in handy one day :)


gravatar

31

permalink this comment Chris Wed Feb 11, 2009 at 09.56 am

Very very cool!


gravatar

32

permalink this comment Christina Wed Feb 11, 2009 at 10.30 am

I really like this design. It is simple and pretty. The mark up needs no arguments, a list is definitely the best way to implement a breadcrumb.

However, I’m not sure if the design would work if “the page you are on now” had a long title that would wrap on to two lines. That is something web designers must consider when handing over the site to a client.

[Edit Veerle: This has been already addressed in this comment]


gravatar

33

permalink this comment James Howard Wed Feb 11, 2009 at 11.00 am

As usual, a concise and useful tutorial with a great end result.

I’ve always been more of a fan of not setting the container (ul in this case) height and instead adding an overflow: hidden or similar clearfix. That way your height is only in the CSS once. Tiny point, though.


gravatar

34

permalink this comment Oriol Torrent Wed Feb 11, 2009 at 03.35 pm

Very useful, and very close to how I do it. While the html is almost the same (I rather prefer to use only classes except when javascript is involved), my css applied to your code would be:


ul, li {
  list-style-type:none;
  padding:0;
  margin:0;
}     
#crumbs {
  display:inline-block;
  height:2.3em;
  border:1px solid #dedede;
  padding-right:0.75em;
}
#crumbs li {
  display:inline-block;
  line-height:2.3em;
  color:#777;
}     
#crumbs li a {
  background:url(images/crumbs.gif) no-repeat right center;
  display:block;
  padding:0 15px 0 0.75em;
}                 
#crumbs li a:link,
#crumbs li a:visited {
  color:#777;
  text-decoration:none;

a:link, a:visited, 
#crumbs li a:hover,
#crumbs li a:focus {
  color:#dd2c0d;
}

Basically:
- I’ve added padding-right to #crumbs
- I’ve added display:inline-block; to #crumbs
- Removed float from #crumbs li
- Removed padding-left from #crumbs li
- Added display:inline-block; to #crumbs li
- Changed padding:0 15px 0 0; to padding:0 15px 0 0.75em; from #crumbs li a

I added display:inline-block; and padding-right:0.75em; to #crumbs because I normally share the area or the line for the breadcrumb with something else (like a date or a version number) on the right hand side, or because I want to set a fixed width of the ul#crumbs avoiding the clearing problems.


gravatar

35

permalink this comment ron Wed Feb 11, 2009 at 07.11 pm

Excellent ! very usefull combination of a static navigation and a breadcrumb !


gravatar

36

permalink this comment gareth hunt Thu Feb 12, 2009 at 11.47 am

a little disappointed at how basic this post is but perhaps there are still people who haven’t coded breadcrumbs before.

ordered list would have more semantic value because the order of the items is important in a breadcrumb. if you change the order then you change the meaning. hence, ordered list is preferable over unordered list.


gravatar

37

permalink this comment koew Thu Feb 12, 2009 at 12.35 pm

If you’d want to remove the-sometimes-bothersome dotted rectangle around each li-link, you could add outline: none; on the a-styling.


gravatar

38

permalink this comment Veerle Pieters Thu Feb 12, 2009 at 01.26 pm

koew said:

If you’d want to remove the-sometimes-bothersome dotted rectangle around each li-link, you could add outline: none; on the a-styling.

The dotted outline on links is the main visual cue to where the current keyboard focus is on a page. By tabbing or shift-tabbing through the document the focus is set on the next or previous focusable elements. So they serve a very useful purpose and that purpose is critical for a sighted keyboard user to find their way through a page. Removing it is not done since it is an accessibility feature.


gravatar

39

permalink this comment MrFirefly Thu Feb 12, 2009 at 04.46 pm

I was looking for a clear example like this, so thanks a lot :)


gravatar

40

permalink this comment koew Fri Feb 13, 2009 at 12.39 pm

I’d then rather do a more visual hover-effect instead. For instance a background color change or something eye-catching, by using the :focus pseudo-class.

If you really want the sighted keyboard user to easily recognize where they are on the tab-index, make it stand out more. Wouldn’t it be tough on the person with lowered sight/vision to look around for the dotted corners?


gravatar

41

permalink this comment Veerle Pieters Fri Feb 13, 2009 at 01.27 pm

koew said:

If you really want the sighted keyboard user to easily recognize where they are on the tab-index, make it stand out more. Wouldn’t it be tough on the person with lowered sight/vision to look around for the dotted corners?

It is funny that you first say it is bothersome and type a tip to remove it and now you are back suggesting on improving it. Quick turnaround :) It’s already good the standard way otherwise they wouldn’t have implemented it but I like to keep things in balance when thinking about accessibility. Given it a very visual focus will affect other users as well so that’s why I try a moderate approach.


gravatar

42

permalink this comment koew Fri Feb 13, 2009 at 03.15 pm

If you do a sliding doors-trick on the breadcrumb, you could end up with a decent hover-effect that wouldn’t destroy the design for regular users.

And yes, I did turn halfway that’s true. I still would’ve replaced the dotted rectangle.

I partly agreed with your reply and wanted to add some suggestion on making it even more visual/helpful. I’ve worked on accessibility for some time for some clients, and I know it’s important.

The tutorial is a great one, and I really enjoy the scalability-factor you’ve included on the image, making it flexible! How does it cope with IE6’s text resizing?


gravatar

43

permalink this comment peagreen Fri Feb 13, 2009 at 05.53 pm

Awesome tutorial. So simply executed and easy to follow. Thank you!


gravatar

44

permalink this comment Morgan Ney Sat Feb 14, 2009 at 12.56 am

Great simple and effective breadcrumbs with CSS. I like the use of the enlarged arrow graphic to allow for scalability.  I first came across this idea in Dan Cederholm’s ‘Bulletproof Web Design’.  I wonder if you created the breadcrumbs dynamically via filenames or if you hard-coded each trail on each page?  If anybody is interested you can see a PHP script on my blog that dynamically creates a breadcrumb trail based on the pages filename and location. Cheers!


gravatar

45

permalink this comment Nancy Durant Sun Feb 15, 2009 at 03.31 am

I love your blog. I learned about it from a web teacher a year ago and I have learned so much from you.
Now I have added your blog to my rss reader. What took me so long?
Thanks for all you do!


gravatar

46

permalink this comment Nick Toye Sun Feb 15, 2009 at 02.13 pm

Love this effect.  It has the Veerle feel to it.

Especially love the simplicity and the visual effect of the arrows.


gravatar

47

permalink this comment Thomas Sun Feb 15, 2009 at 09.13 pm

Very clear explained! I like the use of the big background-image. Smart solution!


gravatar

48

permalink this comment Leo Degan Mon Feb 16, 2009 at 09.43 am

Nice CSS tip. The WordPress theme “iNove” also uses this well. Anyway, thanks for sharing. I’ve been reading your blog for quite a long time. :)


gravatar

49

permalink this comment David Hamill Tue Feb 17, 2009 at 01.53 pm

The argument between ordered versus unordered lists is one of minutae really. I know you want to be semantically perfect but either will do.

Nested lists would be a little tedious for a screen reader because it would read out the fact that it was a new list and how many items were in that list for each link.


gravatar

50

permalink this comment André Severo Thu Feb 19, 2009 at 12.08 am

Nice tutorial, very simple. Thanks for sharing your wisdom with us.


gravatar

51

permalink this comment Saiprasad Thu Feb 19, 2009 at 04.39 am

Thank you. Simple yet great tutorial.


gravatar

52

permalink this comment Heath Huffman Thu Feb 19, 2009 at 04.46 pm

Nice post!  I like it…. I might just end up using this for all our new Doodlekit layouts.  Thanks!


gravatar

53

permalink this comment lb Fri Feb 20, 2009 at 11.02 am

Excellent article, thanks. I like your large background-image-idea a lot!

One word to the ul: if you skip the fixed height of it and let the ul (parent of floating li’s) float, too, it will automatically fit its size to multilines. Just have to put a width to the ul, so it “surrounds” all li’s

instead of

#crumbs {       
  height: 2.3em;
}

use

#crumbs {
  /* height: 2.3em; */
  float: left;
  width: 100%;
}


gravatar

54

permalink this comment Ryan Fri Feb 20, 2009 at 10.06 pm

Breadcrumb links are great for seo and also provide a lot of value to users. I have been looking for a way to dress them up a bit. This is perfect.


gravatar

55

permalink this comment John Crenshaw Thu Mar 5, 2009 at 07.00 am

Inexplicably, I find myself on your site for the third time in 24 hours. First I was looking for color calculators, then I wanted to spruce up a table, and now breadcrumbs. You’ve blown me away. Keep up the incredible work.



Commenting is not available in this weblog entry.

Flickrness

buy something from my Amazon wishlist