Close Menu

Breadcrumb Trail Using Only CSS

We recently developed a neat little css breadcrumb trail for our appointment flows

We’ve been revisiting the appointment booking process over recent weeks and I’ve been working on a css breadcrumb trail that allows users to see their current position in the appointment booking flow. I’d managed to design something that was a little fiddly to do with css alone, so I thought I’d share with you how I did it.

The problem

On the whole breadcrumb trails can either be extremely simple, text only offerings, of they can be image-laden, html-laden, unwieldy beasts. We wanted something that looked good, was responsive, and relied only on css and text.

This is the design I came up with – I was (semi) confident I could create this in css.

The HTML

We start with a standard list with anchor tags within the li’s. Nice, simple streamlined mark-up

<ul class="breadcrumbs">
 <li><a href="link_to_crumb1">Face to face</a></li>
 <li><a href="link_to_crumb2">Nurse</a></li>
 <li><a href="link_to_crumb3">All available appointments</a></li>
 <li class="current"><span>Early morning appointments</span></li>
</ul>

The CSS

Stage 1 – The Basics

We then add basic styles to the anchor tags to make them inline, give them some padding, a background colour, and a hover colour (with a cheeky transition to animate between the hover colour changes)

.breadcrumbs li {
  float: left;
  display: inline-block;
}
.breadcrumbs a {
  transition: all 250ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
  background: #E1E1E1;
  color: #657778;
  display: inline-block;
  text-decoration: none;
  line-height: 44px;
  padding-right: 6px;
  padding-left: 6px;
  margin-right: 4px;
  padding-left: 18px;
  border-right: 4px solid #fff;
  position: relative;
  &:hover {
    background: #F7C05D;
    color: #000;
  }
}

Stage 2 – Triangle 1

Next, is to add some css triangles in to the mix. This is done using a pseudo element and a handy triangle generator online (I’ve always used this one, I’m a creature of habit an it’s the first google result). The triangle generator uses borders to create a triangle in css. Here’s the example we’re using:

width: 0;
height: 0;
border-style: solid;
border-width: 22px 0 22px 10px;
border-color: transparent transparent transparent #E1E1E1;

We then use this in our breadcrumb. I’ve used the after pseudo element to position it absolutely outside of the anchor tag itself. For this example I’ve also added some margin-right to the anchor tag so we can see the triangles themselves

.breadcrumbs a {
  ...
  margin-right: 4px; // needed for this example
}
.breadcrumbs a:after {
  transition: all 250ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
  content: '';
  display: block;
  position: absolute;
  top: 0;
  right: -10px; // position it outside the anchor tag
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 22px 0 22px 10px;
  border-color: transparent transparent transparent #E1E1E1;
  z-index: 2;
}

As you can see above, this isn’t looking right, we need the buttons to sit next to each other with the triangle being the only divider. Time for another triangle

Stage 3 – Triangle 2

We need to add another triangle behind our grey one. This triangle will be white and will act as our divider.

Here’s the CSS. We’ve used the before pseudo element for this one and it sits 4 px to the right of our original triangle. We need to adjust the z-index’s so that one sits behind the other.

.breadcrumbs a:before {
  content: '';
  display: block;
  position: absolute;
  top: 0;
  right: -14px; // positioned 4px away from the original triangle
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 15px 0 15px 10px;
  border-color: transparent transparent transparent #fff;
  z-index: 1; // lower z-index so it sits below our original
}

We’re nearly there but it’s still not quite right as the white line appears cut off at the ends. This is because the css arrow can only be a triangle, we can’t extend one side to fill the gap we need. In the image below you can see the grey of the next button sitting in between the two arrows. We need to make some tweaks.

Stage 3 – Filling the gaps

We could add margin-right to each button to give us the gap we’re after, which is a perfectly suitable solution. However, in this situation I didn’t want the breadcrumb to have any gaps – this would mean any background colour applied to the parent element would show through, like this…

We also can’t add any more pseudo elements as we’ve used both of the ones at our disposal. And I definitely didn’t want to add any more html to the list, just to fill a silly little gap. Here’s where the border saves the day! By adding a 4px border to the right of our buttons, we can fill the gaps, and get the look we’re after. We also manage to escape the classic designer predicament of designing something then realising you’re not sure how to build it

This solution gives us a flexible breadcrumb that we can easily manage at various screen sizes. It’s clear and accessible from a user perspective, and the developers love us because we’re not adding needless html to a simple list.

Job done, onwards!

Related