CSS: Pipe Delimited List Menus

First of all - what the heck is a “pipe”? The character referred to as a “pipe” ( ), in Linux, Unix, or OSX, is used for redirecting the output of one terminal command into another (ls grep “something”). It is also very commonly used, albiet only for presentation, to delimit individual items of a site navigation or other menu. By now, any professional web developer knows that a menu of any sort belongs inside our good ole friend the unordered list. I won’t go into the benefits of using semantic markup here, but I do want to share my technique for achieving this very common menu style without adding any extra markup or unnecessary characters.

pipe list menu

One technique used for achieving this is to put the characters into the menu directly:
  <ul>
    <li><a href="http://rubyonrails.org">Ruby on Rails</a></li>
    <li>|</li>
    <li><a href="http://w3.org">Web Standards</a></li>
    <li>|</li>
    <li><a href="http://ie7.com/">Hilarious</a></li>
    <li>|</li>
    <li><a href="http://jyte.com/">Fun for Geeks</a></li>
    <li>|</li>
    <li><a href="http://www.prototypejs.org/">Javascript is cool now</a></li>
  </ul>

With this structure one need only display each list element as inline and give them some padding and the result will be the desired pipe separated menu. While this is more semantically correct than using a table or just putting everything in one element in a linear fashion, it is not as correct as it could be. Our markup should instead look like:

  <ul>
    <li><a href="http://rubyonrails.org">Ruby on Rails</a></li>
    <li><a href="http://w3.org">Web Standards</a></li>
    <li><a href="http://ie7.com/">Hilarious</a></li>
    <li><a href="http://jyte.com/">Fun for Geeks</a></li>
    <li><a href="http://www.prototypejs.org/">Javascript is cool now</a></li>
  </ul>

The pipe separator will need to be a background image (as any purely presentational image element should be). Take a screen shot of the pipe, or which ever character you want to delimit your menu with, slice it out, and save it to your images directory.

The next step is to add in some css class selectors to identify the first element in the menu and the last.

  <ul>
    <li class="first"><a href="http://rubyonrails.org">Ruby on Rails</a></li>
    <li><a href="http://w3.org">Web Standards</a></li>
    <li><a href="http://ie7.com/">Hilarious</a></li>
    <li><a href="http://jyte.com/">Fun for Geeks</a></li>
    <li class="last"><a href="http://www.prototypejs.org/">Javascript is cool now</a></li>
  </ul>

With our finished markup in a clean and lean state we can move on to styling it up with some css. We are first going to apply the styles necessary to get the nav to display horizontally. The “display:inline” property is responsible for removing each LI from the document flow and causing them to line up side by side. Setting the width of each li is a must for this to work. I then apply some left and right padding to separate the menu items. I have chosen to use em’s as my unit for padding, margin, etc, but declaring exact pixel values is still perfectly fine.

  .nav li { 
    width:auto;
    margin:0 auto;
    display:inline;
    padding:0 1.5em;
  }

To this same style I also add in my pipe background image. The tricky part here is getting the image to line up correctly with the text. To do this you will need to fiddle with the background-position offset values as well as aligning the background right. On the vertical offset a value of 0.5em seems to work well across most browsers.

  .nav li {
    width:auto;
    margin:0 auto;
    display:inline;
    padding:0 1.5em;
    background:#ccc url(/images/pipe.gif) no-repeat 0 0.5em;
  }

The final ingredient in this recipe is addressing the first and last menu elements. For the left most item we need to clear left padding and for the right most element we need to clear… you guessed it - right padding. We also have an extra pipe floating around on the first element. We take care of all this like so:

  .nav li.first {
    padding-left:0;
    background:none;
  }

  .nav li.last {
    padding-right:0;
  }

That’s pretty much it! Works very well on all the major Windows and Mac browsers. For a look at the final product I have thrown together a very primitive example of the menu for your viewing (and copying/pasting) pleasure.

PS - In case you were thinking hey why does this guy put all of his css styles on a single line?, you are in luck! My method for organizing and formating css just happens to be the topic of my next article.

Disclaimer: The following technique is nothing particularly new or cutting edge. This is simply something I often use and should be considered a “best practices” article for those concerned with web standards and accessibility.

blog comments powered by Disqus