horizontal list separators/a quick how-to

I've touched upon the subject before, but never really explained in detail my preferred way of implementing horizontal list separators (within an em design). Some time ago I wrote an article on css generated content which quickly referenced this technique, but since the usefulness of css generated content is still pretty limited, it might be good to give a quick rundown on how to do this the good way.

setting an example: the breadcrumb

To illustrate the problem, let's take a basic horizontal breadcrumb. Elements within the breadcrumb are typically separated by a > character. This is of course only a visual separator and doesn't belong in the html code. If life was perfect, we'd be using css generated content to insert the > sign through css, but those days are still a long way off. The basic html code for such a breadcrumb is pretty simple:

<ol> <li><a class="page">level 1</a></li> <li><a class="page">level 2</a></li> <li class="last-child"><span class="page">level 3</span></li> </ol>

We've used a simple ordered list and added each level as a list item. In the final design, there should be two visual separators (between item 1-2 and item 2-3).

Also, I know some people might prefer using an ul instead of an ol, I know I could drop the last-child class and I know that I could even drop the .page class, but that is not really part of the scope of the article (and I don't agree to any of the above either).


To accomplish this, we'll use a css background image for the separator. We'll add it to the right of each list element and remove it from the last item. Alternatively, you can add the separators to the left and remove it from the first item. This is a very common setup, and even though there are several (decent) ways of implementing this, your choices are limited when you want a clean and flexible css implementation.

The main problem in em design is that pixels and ems really don't mix too well. Since we'll be using css background images, we'll have to make sure the text won't overlap the image. On top of that, we'll have to push the separators a certain distance away from the breadcrumb text. In most cases, the distance from the separator to the previous item should equal the distance to the next item.

We could add paddings in both directions on the list item, but that would restrict us to either using pixel paddings or to aim for a good em measure. When enlarging your design, this will result in uneven spacings though. We can also use left and right margins on the .page elements, but that leaves us with similar troubles. So we need a better way to handle this.

the solution

li {background:url("..") right center no-repeat; padding-right:8px;} li .page {margin:0em 0.5em;}

The solution is really quite simple. Since the background image is set on the list item, we'll add a padding exactly the same width as the background image (that is, if you cut the image so there isn't any dead space on either side). That way, we don't have to worry about the breadcrumb text overlapping the image. To push the links away from the separators, we'll use equal margins on the .page elements. This way, we can control the padding and spacing separately. This makes it easier to adapt the css when the separator images changes (becomes wider) or the spacing between links and separators needs to be increased.

li.first-child .page {margin-left:0;} li.last-child {background:none; padding-right:0;} li.last-child .page {margin-right:0;}

The three lines above are less important for the article but clean up the breadcrumb css a little. Especially the first and last rules are interesting to note, as many people forget to remove the left margin on the first element and the right margin on the last element. It might not hurt the design, but it is cleaner this way, and that 0.5em of dead space will never be in the way of any other element on the page.


As you can see, this technique is as simple as can be, but it still shows a certain level of detail and attention often lacking in most css implementations. So next time you make a horizontal list with separators, take a little time to implement them the right way, rather than aiming for something that looks okayish but breaks when resizing the font.