horizontal list separators/a quick how-to

May 11, 2009 / 13:08

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).

issues

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.

conclusion

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.

blog archive

All my articles are neatly filed inside the archive. Search and filter your way to the article you like:

contact me

If you want to leave me a quick message or you have any questions, drop me a note.

Comment author
3 comments in total
May 12, 2009 04:09

Alternatively, you can add the separators to the left and remove it from the first item...

why don't you use negative left margin? so there is no need "first-child" & "last-child" classes (or unsupported by IE6 :first-child & :last-child pseudoelements). something like this:


ol {overflow: hidden;}

li {
    float: left;
    display:block;
    list-style: none;
    background: url(bull.png) left center no-repeat;
    padding:0 8px; /* bullet image width */
    margin-left:-8px; /* bullet image width */
    margin-right:0.5em;
}

li .page {margin-left:0.5em;}

I know I could drop the last-child class

you do you know another way?

May 12, 2009 11:53

Well, first of all you have to declare a negative margin = the padding for the image. This means, if you change the image, you need to adapt the padding and the negative margin. Also, if you want to increase your margin, you have to adapt the one on the li element and the one on the .page element. Such type of css is not very flexible and prone to errors. My example has 1 value for the padding to cross the image, and one value to declare the margin separation.

do you know another way?

Well, I could set the background to the .page element and use the span element in the last list item to disable the image.

May 18, 2009 12:52

http://wpthemes.blogohblog.net/ looks eerily similar to this sight. :O

* required fields

Leave your data
Leave a comment