Tutorial, part 1: Creating a breadcrumb-style list with colored arrows using CSS

A step-by-step guide to making those cool overlapping colored boxes with arrowed edges, all in CSS, plus some advice on using SASS to not repeat yourself in your code

Exciting times! I’m in the middle of my first major coding project since graduating DevBootcamp two years ago — I’m doing a complete top-to-bottom overhaul of the website for my arts center, the Chicago Center for Literature and Photography, including both the frontend (how it looks and feels) and the backend (switching its CMS software from the outdated MovableType to the super-trendy WordPress). I’ll admit, it’s been a slog, but that’s just how big coding projects are; progress has been coming dripping along like a leaky faucet, and sometimes I spend literally weeks figuring out how to accomplish an onscreen detail that my visitors will only spend half a second even paying attention to.

I had a pretty nice breakthrough this week, though, that took me forever to figure out how to perfect, so I thought I’d post a step-by-step tutorial here for others who are frustratingly trying to figure it out themselves. Namely, I wanted the list of categories and tags associated with each CCLaP blog entry to appear as a “breadcrumb-style” list at the end of each post, where each tag was its own colored box and that box’s entire right side was a giant arrow pointing to the next box. It’s not an actual breadcrumb list, in that the links don’t directly relate to each other in a hierarchical order from most-general to most-specific; but it’s still a visual style I find sharp, and certainly I think a better way to display a large list of related tags than simply running them vertically in a sidebar like so many other blogs do it.

Before anything else, let’s take a look at the finished, working list, both within the context of an entire blog entry and by itself:

So how did I accomplish it? Well, right off the bat, I want to mention that much of my solution came from this great tutorial by Chris Coyier over at CSS-Tricks.com, a site I obsessively follow as a front-end developer and that you should too. However, there were a few hitches with that article that I needed to work out:

  • Coyier accomplished his list using the actual list tags in HTML (<ul>, <li>, etc), while I did mine through a series of <span> tags with specific classes added (a legacy of the original WordPress code I’m working with, but more about this in part 2); so I needed to figure out how much of his code there was specifically about stripping away the built-in formatting of HTML list tags, versus how much of it was specifically about stylizing the breadcrumbs.
  • Coyier was designing with just a short list of items in mind, so went to the extra trouble of adding a series of gradations to his colored boxes; but since I’m using this in the context of a tag list that might go on for 20, 30 items or more, I decided to skip that entire part of his own tutorial.
  • I use the relative-based em standard for all my sizing, versus the set-in-stone px sizes that Coyier uses in his example; so I needed to make sure that his tricks there about automatically centering the arrows would work with relative sizes.
  • And I’m very deliberately using the SASS pre-compiler for my CSS, because I’m out looking for a job right now and want to show employers that I have a mastery over this commonly used technology. Plus I have another motive for using SASS extensively: I actually studied full-stack coding in DevBootcamp (specifically, Ruby on Rails) before deciding to specialize in front-end work after graduation, and ended up getting sorta indoctrinated in the cult of agile development while there, including an obsession over the adage of “don’t repeat yourself” (DRY) in your code. SASS is great for this when it comes to CSS, but only if you know what you’re doing — it’s basically an attempt to graft object-oriented programming (OOP) on top of CSS, including the opportunity to define variables, do math on those variables, and write your own functions complete with assignable arguments. I’m trying to get in as much practice as possible right now with these more advanced SASS capabilities; so my solution here is not just about accomplishing the proper look, but also writing it in a way so that I can use that code over and over there in that blog footer, adding different colors to the different sections, sometimes adding an arrow and sometimes not, theoretically without having to write even a single extra line of duplicated code in my CSS stylesheet. That’s why my tutorial here is actually split into two parts — today I’ll walk through the solution in plain CSS, for those who don’t use SASS, then tomorrow I’ll show how to use the principles behind Ruby and other OOP languages to wrap the solution up into a series of mixins and variables so it can be used over and over.

So to start out, let’s quickly look at how I set up the actual colored box that the arrow will eventually get added to. This example below is specifically for the blue boxes in the image, the ones that show that entry’s categories:

@import url('https://fonts.googleapis.com/css?family=BenchNine');
.cat-links {
font-family: ‘BenchNine’, sans-serif;
text-transform: uppercase;
font-size: 1em;
font-weight: 700;
color: white;
background-color: #669999; /* blue */
padding: 0 0.25em 0 1.25em;
white-space: nowrap;
position: relative;
}
.cat-links a:link, a:visited {
color: #ccffff; /* light blue */
}
.cat-links a:hover { 
color: #336666; /* dark blue */
}

Note that almost none of this so far has anything to do with making the actual breadcrumb effect work; these are simply the personal choices I made as a designer to determine how my particular box will look, and almost all of it can be replaced with whatever choices you want to make. In fact, the one and only line here that’s important to keep in your own code is the position: relative declaration; that will be important when adding the arrow in the next step.

Making a triangle in CSS is actually a well-documented process that’s been around for awhile; the trick is to give your box a width and height of zero, but with fairly large borders, which come together at their edges as a series of angles:

If you make three of those border edges transparent, then, you’re left with only one, which not by coincidence looks like a triangle:

The CSS code looks like this:

content: " ";
width: 0;
height: 0;
border-top: 0.7em solid transparent;
border-bottom: 0.7em solid transparent;
border-left: 0.7em solid #669999;

Note that the 0.7em size here is specifically to line up with the 1em text and 0 top- and bottom-padding of my particular box. You’ll need to play with this number yourself to get the correct look for your own needs. (Also note that making all three numbers the same value results in a triangle of exactly 90 degrees; you can actually change the numbers in those lines into ones that differ from each other to achieve smaller or larger angles.)

Next you’ll want to have the triangle appear on the exact right-edge of your text box, and to be exactly vertically centered, which is once again a well-documented trick that’s been around for awhile:

position: absolute;
left: 100%;
top: 50%;
margin-top: -0.7em;

Again, the -0.7em seen here is my personal size to work with my personal box; you’ll want to change that number to whatever number you used for your own triangle size. Then to get this to appear in the correct place, you stick all this code into an ::after pseudoclass for your colored box:

.cat-links::after {
content: " ";
width: 0;
height: 0;
border-top: 0.7em solid transparent;
border-bottom: 0.7em solid transparent;
border-left: 0.7em solid #669999;
position: absolute;
top: 50%;
margin-top: -0.7em;
left: 100%;
}

Only one problem, though — since you’re technically using the borders of this box to cleverly create the triangle itself, you can’t use them to make the white border that allows the triangle to actually be seen, once the colored box is laying on top of the next colored box. To accomplish this you need to make a duplicate triangle, with the same exact specs as the first one, but this time white, and display it using the ::before pseudoclass, making sure to “scoot” it over exactly 1 pixel so its edge will actually be seen:

.cat-links::before {
content: " ";
width: 0;
height: 0;
border-top: 0.7em solid transparent;
border-bottom: 0.7em solid transparent;
border-left: 0.7em solid white;
position: absolute;
top: 50%;
margin-top: -0.7em;
left: 100%;
margin-left: 1px;
}

And then finally, to make sure the colored triangle always appears on top of the white triangle, you add a couple of z-index specifications, so that the finished code looks like the following:

.cat-links::after {
content: " ";
width: 0;
height: 0;
border-top: 0.7em solid transparent;
border-bottom: 0.7em solid transparent;
border-left: 0.7em solid #669999;
position: absolute;
top: 50%;
margin-top: -0.7em;
left: 100%;
z-index: 2;
}
.cat-links::before {
content: " ";
width: 0;
height: 0;
border-top: 0.7em solid transparent;
border-bottom: 0.7em solid transparent;
border-left: 0.7em solid white;
position: absolute;
top: 50%;
margin-top: -0.7em;
left: 100%;
margin-left: 1px;
z-index: 1;
}

The colored boxes themselves are by default at a z-index position of 0, which is what makes both triangles appear on “top” of the next box they’re overlapping.

The HTML itself, then, is super-simple:

<p>
Read more about:
<span class="cat-links">Literature</span>
<span class="cat-links">Literature:Fiction</span>
<span class="cat-links">Reviews</span>
</p>

And that’s it! Not counting any proprietary code a designer might use to style their particular page, this should be the minimum amount of code needed to generate the overlapping colored boxes with breadcrumb-style arrows. Remember, though, I’m just an unemployed beginning developer myself; if you see anything I flat-out got wrong here, or would like to make a suggestion for making this code even better, I strongly encourage you to either leave a comment or contact me directly at ilikejason@gmail.com.

Tomorrow in part 2 of this tutorial, we’ll take on the challenge of converting all of this to SASS, so that you can keep repeatedly making more boxes using just one single line of code, even while specifying in that one line of code different colors for each box, different colors for each link, and whether or not that box has an arrow. See you again then!

Show your support

Clapping shows how much you appreciated Jason Pettus’s story.