CSS Design: Taming Lists

As early as July of 1999 I was pontificating on email lists about the virtues of style sheets. Some things never change.

Article Continues Below

What has changed is how I think about CSS, and the underlying structure of (X)HTML to which it is applied. For example, I find that most pages on the web contain a menu of links in a navigation area. These are often marked up as a string of links, often in separate DIVs or paragraphs. Structurally, however, they are a list of links, and should be marked up as such.

Of course the reason that we don’t mark them up in that way is that we don’t want a bullet in front of every link in our navigation area. In a previous article I outlined several techniques for using CSS to layout a web page. One of those techniques involved manipulating a list to display horizontally rather than vertically.

In this article, I’ll demonstrate how to use CSS to bring unwieldy lists under control. It’s time for you to tell lists how to behave, instead of letting them run wild on your web page.

Setting the stage#section2

For purposes of this article, I am using unordered lists. The same CSS can be applied, with similar results, to ordered lists as well. Unless otherwise defined, all of the examples in this article use the following code for the lists.

 <li>Item 1</li>
 <li>Item 2</li>
 <li>Item 3</li>
 <li>Item 4</li>
 <li>Item 5 we'll make a bit longer so
     that it will wrap</li>

Each list is simply placed inside a different DIV, and the CSS is written so that the list’s behavior is determined by the DIV it is in. Each DIV has a base rule:

#base {
 border: 1px solid #000;
 margin: 2em;
 width: 10em;
 padding: 5px;

Without any additional styles applied, the list is rendered in this way in the base DIV:

  • Item 1
  • Item 2
  • Item 3
  • Item 4
  • Item 5 we’ll make a bit longer so that it will wrap


Sometimes the default indent of a list is too much for the design you are working on. But simply changing the margin or the padding of the UL doesn’t work for all browsers. To make the list flush left, e.g., you need to change both the margin and the padding. This is because Internet Explorer and Opera opted to create the indent with the left margin, while Mozilla/Netscape use padding. For more on this see the DevEdge article Consistent List Indentation.

In the following example both the margin-left and padding-left of the UL in the DIV are set to zero:

  • Item 1
  • Item 2
  • Item 3
  • Item 4
  • Item 5 we’ll make a bit longer so that it will wrap

Note that the markers lie outside of the DIV. If the containing box were the BODY of the HTML document, the markers might be rendered outside of the browser window, in effect vanishing. If you want the markers to line up inside the DIV, but along its left side, set either the left padding or margin to one em:

  • Item 1
  • Item 2
  • Item 3
  • Item 4
  • Item 5 we’ll make a bit longer so that it will wrap


Maybe you’ve had a project that required a custom bullet. If so you might have marked it up in a table with one column containing the GIF image bullets aligned top and right, and the other column containing the content of what should have been LIs. With CSS it is possible to use an image as a bullet. If the browser doesn’t support this part of CSS (or doesn’t do images), the default bullet will be used (or you can specify a different HTML bullet if you wish).

The rule looks something like this:

ul {
 list-style-image: url(bullet.gif);

And the browser renders it:

  • Item 1
  • Item 2
  • Item 3
  • Item 4
  • Item 5 we’ll make a bit longer so that it will wrap

To specify an HTML bullet to use if the browser doesn’t support this part of CSS, add:

 list-style-type: disc;

to your rule. Depending on the image that you choose you may find that it doesn’t align itself with the list items the way that you intend. In that case you may choose to have the image be placed within the list item block (rather than outside the block). Adding the following:

 list-style-position: inside;

to your rule will make that change. These three declarations can be combined into a single, shorthand declaration as illustrated in the following rule:

ul {
 list-style: disc url(bullet.gif) inside;

which is the equivalent of:

ul {
 list-style-type: disc;
 list-style-image: url(bullet.gif);
 list-style-position: inside;

This is what it looks like in the web page:

  • Item 1
  • Item 2
  • Item 3
  • Item 4
  • Item 5 we’ll make a bit longer so that it will wrap

There may be times when you have a list, but you don’t want any bullets, or you want to use some other character in place of the bullet. Again, CSS provides a straightforward solution. Simply add list-style: none; to your rule and force the LIs to display with hanging indents. The rule will look something like this:

ul {
 list-style: none;
 margin-left: 0;
 padding-left: 1em;
 text-indent: -1em;

Either the padding or the margin needs to be set to zero, with the other one set to 1em. Depending on the “bullet” that you choose, you may need to modify this value. The negative text-indent causes the first line to be moved to the left by that amount, creating a hanging indent.

The HTML will contain our standard UL, but with whatever character or HTML entity that you want to use in place of the bullet preceding the content of the list item. In our case we’ll be using », the right double angle quote: ».

  • » Item 1
  • » Item 2
  • » Item 3
  • » Item 4
  • » Item 5 we’ll make a bit longer so that it will wrap

I should point out that Netscape6/7/Mozilla (and other Gecko-based browsers) and Opera can create generated content via the CSS2 :before pseudo-element. We can take advantage of this to automatically generate the » character (or any other character) for the bullets. This allows us to leave the content of the UL alone. If you are using Opera or a Gecko-based browser, the following CSS will create the same list as above, but using the standard UL with no extra content:

#custom-gen ul li:before {
 content: "\0BB \020";

The content property may contain strings, URIs and more, including special characters. When using these characters, like », it is necessary to encode them as their escaped HEX equivalents. For the right double angle quote, we use \0BB (the other character, \020, is a space). The final result (remember, the character will only be visible in Opera or Mozilla/Netscape):

  • Item 1
  • Item 2
  • Item 3
  • Item 4
  • Item 5 we’ll make a bit longer so that it will wrap

Truly inline lists#section5

Who says a list needs to be vertically aligned with bullets hanging off the left side of each item? Perhaps you want the structure of an ordered list of links, but visually you want it to look like a vertical navigation bar on the web page. Or maybe you want your list of links to align themselves horizontally across the top of your page.

This applies to more than just lists of links. There are times when you might need to list several items in the midst of a paragraph, maybe a list of books that you want to read. Structurally it makes sense to mark this up as a list, but presentationally you might not want break the flow of the paragraph. CSS to the rescue again!

Since this list will not be separate and unto itself, I won’t put it into the base DIV that the previous lists have inhabited. This time the markup will be a paragraph, followed by the same list, followed by another paragraph.

I hear you crying,“FOUL! I thought you were going to put a list inside of a paragraph, not between two paragraphs.”

To which I reply,“Well, yes. But (X)HTML does not allow a list to appear inside of a paragraph. However, with the help of our style sheet, that is how it will look in the web page.”

Here’s what the styles look like:

#inline-list {
 border: 1px solid #000;
 margin: 2em;
 width: 80%;
 padding: 5px;
 font-family: Verdana, sans-serif;
 }#inline-list p {
 display: inline;
 }#inline-list ul, #inline-list li {
 display: inline;
 margin: 0;
 padding: 0;
 color: #339;
 font-weight: bold;

The markup consists of a <div id=“inline-list”>. This DIV contains a paragraph followed by our standard UL, and a followup paragraph. The UL list has been modified so that each list item has a comma after it, with the last item followed by a period.

The results are below (list appears bold and blue):

A bit of text before the list appears. Perhaps the context is something about a husband getting a call from his wife to pick up a few things on the way home from work. It doesn’t really matter, for our purposes we just need some preceding text before the list:

  • Item 1,
  • Item 2,
  • Item 3,
  • Item 4,
  • Item 5 we’ll make a bit longer so that it will wrap.

And then there is the text that follows the list in the paragraph. One or two sentences is sufficient for the example.

As in the custom bullet example above, we could use CSS to automatically generate the commas and period that follow each list item. If all you had to worry about were Opera and Gecko powered browsers, that is. This time the styles would look like:

#inline-list-gen ul li:after {
 content: ", ";
#inline-list-gen ul li.last:after {
 content: ". ";

Here we use the :after pseudo-element to add a comma after each list item, and a period after a list item with class=“last”, resulting in the following (remember, it will only be visible in Opera or Mozilla/Netscape):

A bit of text before the list appears. Perhaps the context is something about a husband getting a call from his wife to pick up a few things on the way home from work. It doesn’t really matter, for our purposes we just need some preceding text before the list:

  • Item 1
  • Item 2
  • Item 3
  • Item 4
  • Item 5 we’ll make a bit longer so that it will wrap

And then there is the text that follows the list in the paragraph. One or two sentences is sufficient for the example.


As I mentioned previously, the menus of links that appear on nearly every site should really be marked up as lists, since that is what they are. Since we usually don’t want the default list style to apply to these links, we can use CSS to change the way they appear on the page. As we saw above, lists can be forced to display horizontally (inline) rather than stacked vertically (the default behavior). When you do this the bullet goes away and you have many choices about how to separate the list items.

These examples of horizontal lists will all use the same base DIV with the following styles:

#h-contain {
 padding: 5px;
 border: 1px solid #000;
 margin-bottom: 25px;

The next two examples use the same UL as in the previous examples, but without the final list item with its extra text. They also include an additional class that sets apart one of the LIs in the list.


A pipe character, |, is often used to differentiate between choices. It is an obvious separating character, and can be emulated by adding borders to list items:

#pipe ul {
 margin-left: 0;
 padding-left: 0;
 display: inline;
 } #pipe ul li {
 margin-left: 0;
 padding: 3px 15px;
 border-left: 1px solid #000;
 list-style: none;
 display: inline;
#pipe ul li.first {
 margin-left: 0;
 border-left: none;
 list-style: none;
 display: inline;

Here we add class=“first” to the first LI so that it does not end up with a border on its left side.

  • Item 1
  • Item 2
  • Item 3
  • Item 4

You can modify these styles to create a tabbed navigation effect:

#tabs ul {
 margin-left: 0;
 padding-left: 0;
 display: inline;
 } #tabs ul li {
 margin-left: 0;
 margin-bottom: 0;
 padding: 2px 15px 5px;
 border: 1px solid #000;
 list-style: none;
 display: inline;
#tabs ul li.here {
 border-bottom: 1px solid #ffc;
 list-style: none;
 display: inline;
  • Item 1
  • Item 2
  • Item 3
  • Item 4

In this example adding class=“here” to an LI creates a bottom border that matches the background color to indicate that the tab refers to the current page.

Note: This technique was first proffered by Randal Rust, and then riffed on by many on the css-discuss email list

Breadcrumb trails#section8

Another list of links that typically has a horizontal orientation on a web page is what has become known as breadcrumbing. Breadcrumbs show you where you are in the hierarchy of a site, starting with the home page and drilling down to the current section or page. If you really want to make the markup meaningful, you would want to create a series of nested lists, since each new section is part of the section before it:

<div id="bread">
 <li class="first">Home
<li>» Products
 <li>» Computers
  <li>» Software</li>

creates the following:

  • Home
    • » Products
      • » Computers
        • » Software

Adding the following rules to the style sheet for the page:

#bread {
 color: #ccc;
 background-color: #006;
 padding: 3px;
 margin-bottom: 25px;
 }#bread ul {
 margin-left: 0;
 padding-left: 0;
 display: inline;
 border: none;
 } #bread ul li {
 margin-left: 0;
 padding-left: 2px;
 border: none;
 list-style: none;
 display: inline;

creates this:

  • Home
    • » Products
      • » Computers
        • » Software

Again, we can generate the » character (or any other character you might want to use as a separator) with the :before pseudo-element, combined with a class=“first” so that the first LI doesn’t generate a separator:

#bread-gen ul li:before {
 content: "\020 \020 \020 \0BB \020";
 color: #ff9;
#bread-gen ul li.first:before {
 content: " ";

And the end result:

  • Home
    • Products
      • Computers
        • Software

In the Real World#section9

I’d like to end with a real world application of some of the techniques that have been discussed here. We’ll use a standard UL containing links to create a dynamic menu with hover effects. In order to obtain the hover effects we’ll let the UL provide the structure, and the anchor styles will provide most of the visual effects.

This menu of links is actually a solution to a question posed by Michael Efford on the css-discuss list. Michael had created this exact effect using a table, images, and JavaScript. He asked the list if it could be done with CSS. I took the challenge, and with the help of several other members who tracked down some browser specific issues, we came up with a style sheet that works on this markup:

<div id="button">
 <li><a href="#">Home</a></li>
 <li><a href="#">Hidden Cameras</a></li>
 <li><a href="#">CCTV Cameras</a></li>
 <li><a href="#">Employee Theft</a></li>
 <li><a href="#">Helpful Hints</a></li>
 <li><a href="#">F.A.Q</a></li>
 <li><a href="#">About Us</a></li>
 <li><a href="#">Contact Us</a></li>

Let’s look at the style sheet rule by rule, and I’ll explain why each rule is constructed the way that it is.

#button {
 width: 12em;
 border-right: 1px solid #000;
 padding: 0 0 1em 0;
 margin-bottom: 1em;
 font-family: 'Trebuchet MS', 'Lucida Grande',
   Verdana, Lucida, Geneva, Helvetica, 
   Arial, sans-serif;
 background-color: #90bade;
 color: #333;

The first rule is for the #button DIV. It defines the space that the menu will occupy, and provides a context for the menu so that we can define the way the list and links will behave inside the DIV. I chose to make the menu fluid, based on the browser’s font size preferences, so (almost) all units are in ems. This includes the width of the menu. The solid black border on the right was based on the original design from Michael. The bottom padding is there to extend the DIV down beyond the menu of links so that you can see the background of the DIV. Again, this follows the original design. The bottom margin is to separate the DIV from what follows it. The colors came from the original design.

 #button ul {
  list-style: none;
  margin: 0;
  padding: 0;
  border: none;
 #button li {
  border-bottom: 1px solid #90bade;
  margin: 0;

Next I defined what the list will look like. Since all the list items were to be links, and the rollover functionality would be built into the CSS for the links, I essentially removed all styling from the lists. I did add a single pixel border on the bottom of each link that matched the background of the #button DIV, to work as the separator. In the original design, this was an image.

 #button li a {
  display: block;
  padding: 5px 5px 5px 0.5em;
  border-left: 10px solid #1958b7;
  border-right: 10px solid #508fc4;
  background-color: #2175bc;
  color: #fff;
  text-decoration: none;
  width: 100%;
  } html>body #button li a {
  width: auto;
  } #button li a:hover {
  border-left: 10px solid #1c64d1;
  border-right: 10px solid #5ba3e0;
  background-color: #2586d7;
  color: #fff;

Finally, I defined the links. The original design has 10 pixel borders on the right and left. These borders, along with the background, change color on the rollover. This is a relatively simple thing to control with the :hover pseudo-class in CSS, so I put this style into the anchor styles.

There is one workaround in this part of the style sheet. To make the links active for the full width of the DIV, I made them display: block;. This works for everything but IE/Windows. If you give the block an explicit width of 100%, then IE/Windows plays along. But doing this creates problems with IE5/Mac and Netscape/Mozilla. So I used the child selector“>” to redefine the width to auto. Since IE/Windows doesn’t understand child selectors, it ignores the rule. IE5/Mac, Opera and Netscape/Mozilla follow the rule, and everyone is happy.

The rule for the :hover pseudo-class creates the color changes on the backgrounds and borders when the links are moused over.

The style and list markup (about 1K worth) replaced about 5K of JavaScript and TABLE markup, not to mention another 8K or so of images for the rollover effects. It also made the markup more readable, and easier to update, since you no longer need to create new images if a link name changes. Now you simply modify some text. You can view the final result in the context of the site on the Asset Surveillance web site.

Tip of the Iceberg#section10

Believe it or not, we have just scratched the surface of what can be done to modify lists with style sheets. I won’t claim that all of the techniques presented here are the most practical CSS that you’ll come across, but I do hope they make you think about how using CSS can release you to use more structured markup.

181 Reader Comments

  1. I will probably use this article as a reference when I talk about “advanced styles” in my XHTML class.
    Although I’m not going to and re-author all my breadcrumbs in my existing pages.

  2. Perfect! I was just wrestling with how to handle a list of links yesterday! Not only does this answer every question for my personal site, it solves a thorny issue for a menu on a site for my job. Thanks so much.

  3. I’m just saying somthing… this was okay. it’s not like you need a big long article about it, but, it’s cool. I’ll probably end up using something in here sometime or another. Thanks ALA

  4. One thing I think this article lacked was a reference when using the class=”first” and class=”last” examples for specifically styling the first and last elements of lists. Instead of having to embed this in your HTML with an ugly class, you can use the CSS2 and CSS 3 selectors :first-child and :last-child respectively.

    Hence li.first becomes li:first-child (li element which is the first child of its parent element), and li.last becomes (li element which is the last child of its parent element). As far as I’m aware, it’s only supported in Mozilla at the moment, but if you’re talking about examples which only work in Mozilla and Opera, you might as well include those examples too.

    Apart from that, a great article Mark!

  5. Thanks, Lach. Maybe the reason Mark excluded those CSS2/3 selectors from his article is that they are poorly supported in many popular mainstream browsers and he wanted to offer only practical advice.

  6. Nice article, it will come in handy in our work.

    One thing though, when viewing the article using IE6 the real world navbar jumps to the left on the page when the mouse enters. It then remains there without problem unless the page is refreshed and then it jumps again to the left on mouse over. I did follow the link to the Asset Surveillance site and here the menu stays in place.

    Why would this happen?

  7. Yes, sweet article, I too noticed the jumping IE6 phenom, for what it’s worth, it is IE6 on a WinXP box for me.

    No movement noted in NN6.2.3.

    And there appears to be no movement in IE5.5 on a cranky old Win98SE powered P166 either. Go figure.

  8. While we’re doing a forsenic exam, I also noticed in your first positioning example, where you set margin and padding to zero, and suggest
    – “Note that the markers lie outside of the DIV. If the containing box were the BODY of the HTML document, the markers might be rendered outside of the browser window, in effect vanishing.”
    I noticed immediately, they vanish in both IE6 and IE5.5 anyway.

  9. The menu system doesn’t jump when taken out of the ALA code framework, so maybe there is some conflicting styles somewhere that are causing the problem. Furthemore, the rollover effect seems sluggish on IE6 PC when viewed within the article, it’s much faster when by itself.

  10. 1. Why throw things into a div#button? You could move that part of the styling to the ul, maybe adding .menu so that you can have one or several lists of that type in the page along with regular uls.

    2. One thing I found missing here is the definition lists. With definition lists you are from the beginning rid of the bullets, and can throw in a description of the link in the definition data tag. Then you can supply the user with two alternate stylesheets, one with definition data displayed, the other with it hidden.
    (Using a style switcher such as the one Paul Sowden presented in an earlier ALA article, or the one I created for my page. Or serverside. Or the mechanism built into mozilla.)

  11. Heh, I noticed this article on ALA just after I was looking at part of w3c’s XHMTL2 working draft… more particularly, the part about the nl tag.

    Great work 🙂

  12. I have been using lists and css to make my menus for a while now, and it took a while to see how to make them do exactly what I wanted. The inline list is especially nice because it works in text-only as well as visual browsers.

    Most importantly it means we are using the proper markup for the data. Eventually if all the data on the web is marked-up properly, then search engines can do stuff like searching for lists with class “grocery” and qutoes with class “famous” or “thomas-jefferson” — wouldn’t that be nice?

  13. I too, just yesterday, was again looking for a better solution for my menu lists. Thanks for the great article!

  14. Great article. I’ve been trying to implement ul for the menu on a design I’ve been working on.

    I’m having trouble creating a verticle navigation bar with a ul.

    Is it possible to have the list items to take up a percentage of the container div (say 14%) and display inline.

  15. I’m glad the article is being of help to some of you – that’s why I wrote it.

    As apartness noted, I’m pretty much into practical stuff, so I didn’t go into CSS2/3 beyond the generated content (and that only because 2 of the 3 standards compliant browsers support it). I also didn’t mention the proposed NL (which, from what I’ve read about it) will be quite nice once implemented by the browsers. As for DLs – they could take up a whole ‘nother article them selves, and this one was already getting long. Maybe I’ll write something up on Real World Style.

    Thanks again for all the kind words – glad you are liking it!

  16. Definition lists actually do quite well with bullets (especially if you use a list-style-type such as square or circle that you don’t see as much). I use definition lists everywhere on my site for changelogs, link lists, etc. and bullets really help when you’ve got multiple terms or definitions in one entry.

  17. You talk about the power of CSS in your article.
    Thats nice and so but in real world simple things cannot even be put into CSS and therefore I think old good table-layouting is what will stay for 10 years, as css lacks much features, or maybe I am too ignorant to use them in which case you could post an example here or add additional paragraphs to your article covering my question…

    Ofcourse the navigation links are likely lists, but lets
    face it, I cannot do what I am told to do with CSS.
    Look at the

    and say how do I suppose to have that bullet image v e r t i c a l l y centered to the LI contents, or the othe question would be – if thats impossible with lists+css, then how do I fake it with DIVs ?

    With Table-layouting this is a very simple task, but how the things should be done with css – I have NO IDEA!!
    Any feedback welcome…

  18. I’m a web-design novice who is ready to learn. But, I want to learn it right, rather than just learn what I can to make it look good on my personal website. I think this article will really help me. I too, have created my menu using a table, JavaScript, and images. You can see it at http://fresco.freeyellow.com. Please be aware that all the non-compliant markup *will* make you cringe.
    Anyway, the rollover is really slow for me, since I have a dial-up connection, and I’d like to change it, since it rolls over fast and renders fast. My only problem is that my buttons use a freeware font called Neuropol, that I really like, and would like to keep if I can, but I know not nearly everyone who may come across my site will have it on their system. What’s the solution to this? Just set the style to that font, and declare some back-up fonts for those that don’t have it? I like the idea of separating style from content, but there *is* still the issue that I am presenting my artwork on the web, and I want my website to look the way I want it to look. Am I just being a web-Nazi here, and do I need to just loosen up and realize that it’s not too big a deal?
    Please advise and thanks. 😉

  19. I had come across the idea of inlining lists to make horizontal menus a while ago, and implemented one example of such on my personal website (http://www.rephorm.com).
    It’s good to see an article with more details and ideas. The results are very clean and managable menu source. To add an item, merely add an

  20. .
  21. Man, I’d been trying to solicit an article on this from ALA for months… glad to see the subject finally hitting the site.

    I recently got to design out semantic markup, XHTML and CSS into the recent redesign of RES.com — We were in an incredible rush to match the re-launch of the magazine, so the templates are not as far along and I’d hoped them to be by launch, but we’re continuing to update and refine them on a daily basis, pretty much.

    I think we hit the criticals: using styles on sematic markup like h1 and ul as much as possible, using absolute positioning and ordering main content at the top of the code for text and spoken browsers and slow connections, etc. There were some realistic compromises like using tables when certain table layout was needed and keeping the embed tag for flash (alt navigation is coming shortly). I would have liked to tap into pseudo-classes, multiple classes, and advanced selectors but they’re not quite there yet. But there’s enough in the browsers now that moving beyond Netscape 4 for our audience was a reality, and I’m hoping that it will help others either as inspiration, or at least a working example in a commercial site. 🙂

    Anyone know of any other commericals sites doing the same? I’m very curious.

  22. How about taking that real world example on more step? The next step is showing secondary menu items that are indented, and which are members of a list within a list.

    Hidden Cameras
    Wide angle
    CCTV Cameras
    Employee Theft

  23. I noticed the IE6 “jump” as well — and on top of that it causes the right-side menu on ALA to flop down to the bottom of the entire page, thus destroying the layout, in effect.

    To be honest, I’ve noticed this so-called “jump” effect on my own pages and just thought I was a sorry-a coder of CSS. So I guess now I’m a bit happy it isn’t just me.

    Now, of course, I’m also worried that we’ve discovered an IE6/Win bug for CSS. In fact, just last night I was coding something, marked/coded an “a href” tag when added to a similar ALA-ish nav on my own quickly thrown together Web site and when I hovered over the mailto: the page jumped and bashed the nav all to bloody heck!

    Any thoughts? Do I experiment more, post what I got somewhere so we can iron this out? Suggestions? Of course, we could keep this off the list and via email for anyone that has suggestions, etc. since I don’t know if my post here is totally on topic.


    -_- D.

  24. Hi everyone! I’d like to know if one can move the strike line in relation to a character. I.e, with certain font familys, if you strike a 0 (zero), it will seem like an 8 (eight). Is there any way to prevent it?

    Thanks in advace,
    best regards,

  25. First of all, I want to say I’m very glad with the article and the way it shows what you can do if you push your CSS skills.

    Second of all, I want to say I’m 100% for seperating (semantic) markup from presentation, so please don’t throw bombs at me for not agreeing on that either.


    So far I haven’t read any discussion about the fact that the current state of CSS means you need to invest a lot to develop a technical skill. CSS is yet in an toddler state when it comes to user-friendliness.

    Let me explain: if you own a corporate website, you hire people to do the presentation (i.e. CSS knowledgeable people and/or designers), you hire people that take care of the back-end and you want a system that enables your (decentralized) content producers to add new content to your website like they would be typing a Word document, so no technical skills required. right?

    But the web is not a coporate place. Let’s say you are an enthusiastic amateur historian and you know everything that happened to the place you live in since 1426. So want to share your enthusiasm and knowledge and you make a website on which you publish your latest discoveries.

    Our amateur historian is probably not a web-techniques-savvy person, so he or she does use, let’s say MS Frontpage, to produce and maintain the website. Goodbye seperation of structure and presentation, unless they push the right buttons by accident.

    From an information point of view, that particular website could do very well with a good structured markup, so the likelihood that everyone in the world looking for the history of that particular place would end up on that website will be more likely. Am I right?

    Sadly, if CSS gets more developed and more and more professional web producers start to make all those wonderful pages where markup and presentation is perfectly seperated, the information sources like our amateur historian will be pushed further and further into the dark corners of the WWW. While the website itself could be a unique and high valued source of specific information.

    Unless Microsoft Frontpage will become so smart it produces the correct code. But my guess is that CSS (or any next generation language) needs to be developed into a more userfriendly tool first to be able to achieve that.

    Any opinions about this? And the implications for the WWW as a little less unstructered information source?

  26. It’s a bit off-topic, but what you’re saying really comes down to a more basic fear that professionally designed and developed websites may marginalize less professionally designed and developed sites. In the case of your amateur historian, Google is the ultimate arbiter. If your hypothetical historian has written text and meta data with half an eye on the way search engines work, his or her site will get plenty of traffic from Google and AllTheWeb and other well-made search engines. If the content has merit it will retain many of its visitors, though if it’s badly designed or has poor usability some percentage of those visitors will leave. Likewise if it’s badly written many visitors will leave. But none of that has much of anything to do with the comprehensibility of CSS1 and CSS2.

  27. Strange effects in IE6 seem to me to be common – I have an unordered list forming the menu down the left hand side at http://www.elandigitalsystems.com. I used CSS to make it change colors on roll-over and do other pretty stuff which is just great. However I did find that IE6 (and I think only IE6) knocks the top item in any list sideways.
    Unable to find any solution I followed a kind suggestion from the CSS-discuss list to include a dummy list item at the top of each list and set display:none for this item in my CSS. That seems to look OK but I wish I knew what causes the problem…

  28. Thanks for the article — it’s a very useful compilation and distillation of some valuable techniques.

    I want to disagree on your proposed HTML markup for breadcrumbs. Each breadcrumb should be a list item, not a nested list. If I give you directions to my house, it’s a list of landmarks, not a hierachy of every street in the city.

    I think, though, that it should be an ordered list, since it’s from top to bottom. Changing the order of the breadcrumb list would make a difference in the way it’s interpreted. CSS would hide the numbers and use symbols, as you’ve shown.

    Just my 2 cents worth. I really appreciated the article because it so neatly traversed from theory to practical examples.

  29. In reality, however, you cannot compare breadcrumbs to real-world directions, since your “list of landmarks” is only going to ONE area–your house. Whereas online, a website will have many more destinations, and would therefore use a nested navigational style to sort them. Breadcrumbs are usually used in a directories, your suggestion would probably be more appropriate as a navigation bar–or for giving directions. 😉

  30. I was thinking that ALA was slipping in content lately, but this was a fine article. Good work, ALA.

  31. Mark’s article is excellent. It will prove to be a useful reference for me in the future. I’ve always had to wrestle with lists a bit and now Mark has given me some good pointers to make things easier.

    I am looking forward to seeing what can also be done with the new element, to be introduced in XHTML 2.0:
    Perhaps we will be able to enjoy JavaScript-free, drop-down menus sometime in the future.

  32. Martijn ten Napel responded at http://www.alistapart.com/stories/taminglists/discuss/2/#ala-1019

    Just to continue briefly with this “branch topic”, Martijn says “Is well structured (X)HTML not one of the best ways to climb the rankings of the search engines? ” I agree completely with this. A well structured document that is free of the bloat of presentational markup will probably get a higher ranking than documents that mix content and presentation because the information that is being sought will be more accessible to the search engine, as well as the user.

    I believe that using list markup for creating navigation menus is good move, but it is also probably a good idea to move this markup to the end of a document and then use CSS-P to pull it back up to the top, if at all possible. That means that users with screen readers (and the like) need not be constantly wading through a navigation list everytime they click to a new page.

  33. Mark mentioned that I started the thread at CSS-Discuss. I’ve been working with ULs for quite some time now to create menus. Mostly due to accessibility reasons. And one day, driving to work, listening to Ryan Adams, I thought to myself, “Why couldn’t you make tabs with a UL and some CSS?” So I whipped something up, posted it to my site, http://www.r2communications.com/cssTests/tabbedMenu.html and posted it to the list. I was quite impressed in how people took it and ran with it. Great article, Mark.

  34. Great article, Mark.

    I would just like to note that the Plone Content Management System (which I have designed the CSS for) – http://www.plone.org – has had the type of CSS-generated tabs you describe here for over one year now. I am not claiming I invented them (don’t know when Randall came up with his, and the two are probably unrelated “discoveries”), but Plone has used these since July 2001.

    Again, thanks for a great article, I really like the real-world examples, and you even taught me some new stuff I hadn’t thought of 🙂

    — Alexander Limi

  35. A typical tab group in Plone looks like this:




    and the corresponding CSS is:

    div.tabs {
    border-collapse: collapse;
    border-bottom-color: #8CACBB;
    border-bottom-style: solid;
    border-bottom-width: 1px;
    padding: 0.5em 0em 0em 2em;

    div.tabs a {
    /* The normal, unselected tabs. They are all links */
    border-color: #8CACBB;
    border-width: 1px;
    border-style: solid solid none solid;
    color: #436976;
    margin-right: 0.5em;
    padding: 0em 2em;

    div.tabs a.selected {
    /* The selected tab. There’s only one of this */
    background-color: #DEE7EC;
    border: 1px solid #8CACBB;
    border-bottom: #DEE7EC 1px solid;
    color: #436976;

    and it ends up looking as the page on http://plone.org

    I think it is a smart way of creating a tab row for section navigation, and it degrades nicely too. And look at how extremely simple and clean the HTML ends up being 🙂

  36. Hi – is it poss to get the links centered between the pipes? In the example they are set over slightly to the left.
    Great stuff Mark

  37. Near the end of the article, Mark comments, “If you give the block an explicit width of 100%, then IE/Windows plays along. But doing this creates problems with IE5/Mac and Netscape/Mozilla.” This is precisely the problem I’ve been wrestling with in my code. I have parent div wrappers at fixed widths, and inner divs with width set to 100% of immediate parent. In IE/Win AND IE5/Mac, everything lines up beautifully. In Netscape/Moz and Opera, it, of course, does not. I was wondering if anyone might be so kind as to point me to an article discussing this issue, and possible workarounds? I’d rather not resort to specifying all widths to the pixel, but will do whatever it takes to make the layout render readably in all major browsers.

    Thanks for your time,

  38. This aarticle was great – Ive been trying to find a decent way to display my links and yet still make them accessible – thanks for this! – I too noticed the whole shifting thing in IE6 – good job that i use netscape at home (6/7) its alot faster 😀

  39. great article!

    got a problem though…
    when presenting a nested list as a vertical navigation menu
    for example:

    the nesting level indentation can be achieved by padding-left on li;
    however, with these paddings, is it still possible to changing the
    entire row background color on hover of the menu item li link?

  40. A very nicely-written tutorial. Often it’s hard to just find a tutorial on the subject that you want let alone find one that is so clear. Thanks, Mark! You did an excellent job.

  41. This was a good article, but unfortunately seemed to miss the one point I haven’t been able to solve. Image bullets don’t seem to align *horizontally* to the lists. Even in the 2 examples, you gave the images are too high (on OS X, IE5). Unfortunately, the behaviour seems to differ between IE and N (not sure about Windows).
    Any ideas?

  42. IMO, the inline lists one is unneccessary and the UL was not supposed to be used in this way.

    Why? Well look at the list without the stylesheet. It doesn’t look like as it was intended because now you have two paragraphs and a block list in between. Structually, it is a single paragraph, the list is contained inside (which is invalid HTML), and structually, it is an inline list (for which there is no HTML markup), not a block list like UL. So I say it’s best to leave the list unmarked.

    Also, by looking at the other lists without the stylesheet, you can form a clearer opinion about what’s right and what’s wrong. eg. For the breadcrumbs, the nested option is more “correct” than a single list IMO. When you look at it without styles, each item is indented more than the last, and looks well… right.

  43. I love working with CSS and would gladly throw out tables for everything except tabular data (which this article even gives alternatives).. but in the end I can’t. I panic. I seize up. I create the page, it looks great in the three browsers I have access to, but I can’t trust that it will look good in all browsers. What can I do?

    Do all you guys have a set of machines with different browser/OS/version combinations? How realistic is this for the average joe-blow?

    I would love a service where I could provide my URL, select an environment and receive a screenshot in my email. Anyone know of something like this? Any help appreciated.

  44. I resolved the problem of the intermitent line rendering in mozilla by moving the line
    border-bottom: 1px solid #90bade;
    from #button li to #button li a
    I did some other edits too that may have affected it, and I may have broken something else in attemting to fix it. But it does what I requre of it.

  45. With regards to the horizontal lines only appearing every other button in Mozilla.

    I copied the code and pasted it into a demo page, everything works properly there. I suspect that the code is in conflict with something on the ALA site.

  46. I am curious as to whether or not the margins and padding of a box can be colored. If so, that would dramatically cut down on the number of nested div boxes needed for some simple effects.

  47. Here’s another good CSS tutorial I found on the Internet:


    It’s interesting in that it uses an H1 tag for the name of the site
    (like a classic old style page) but refines h1 to include an image rather than text… Sounds wonderful to me.

    Alistapart folks – can you write a new tutorial based on the concept,
    you know, advantages and disadvantages, how to go around them.
    I like the h1 because it should help with the search engines… 🙂

  48. Ok, I’ve set up an inline list (unordered) as a menu across the top of my site.
    I placed it in a table cell (using XHTML transitional), and gave it a background color. The list shows up right in the middle of the cell in Moz 1.1, but it floats to the top in IE6. I changed the cell’s valign to bottom but it doesn’t do anything. Has anybody else noticed this?

  49. Excellent article, it certainly cleared up some design issues for me.

    One more question:
    How does one control the huge gap between the preceding text and the first list item in a basic page?

    random text

    • item 1
    • item 2
    • item 3

    any ideas?
    Thanks again!

  50. Can we have some article about Content Management Systems (like phpnuke, postnuke, etc) and CSS? These systems tend to be heavily tables based and it’s a pain to get them to be pure CSS. Any hints and tips?

  51. So … how to handle nested lists – is there an HTML-compliant way of doing this? A

    nested inside

    • isn’t legal, is it?

      Advice appreciated…

  52. My mistake …

    is OK.

    isn’t. Which is what I was trying to validate. Doh!

  53. I’m a CSS newbie and I’m confused by the example’s use of the “>” character in the html>body selector. When I check that CSS code through Web Design Group’s CSSCheck, I get this error:

    Selectors may contain only the characters A-Z, a-z, 0-9, Unicode 161-255, hyphens, or escaped Unicode characters as numeric codes.

  54. An excellent article that was exactly what I was looking for. Very useful and simple to implement.

    My only bitch would be Netscape 4.5 on the PC, it can’t read it at all!

  55. An excellent article that was exactly what I was looking for. Very useful and simple to implement.

    My only bitch would be Netscape 4.5 on the PC, it can’t read it at all!

  56. I advice all developers to keep their site’s support for Netscape 4.x at functionality level. E.g. you design may crash, but all functions will be accessible. That’s how were do now in our studio

  57. Hi

    I’m following on in what I think is the spirit of the articles in using lists for nested navigation.

    How do the panel suggest I deal with navigation nested more than one level deep? ie:

    – Section 1
    – section 1: subsection a
    – section 1: subsection b
    – section 1: subsection c
    – Section 2
    – section 2: subsection a

    Assuming that the sections should be in list format, I tried the following and would appreciate thoughts, comments and feedback…

    Validation chokes on this:

    • Main Administration

    because the nested UL is not contained within an LI tag.

    However this validating code:

    does not look right (when unstyled) with the floating bullet above the first list.

  58. Mozilla consistently has 1px rounding errors, as noted by Big John above. His page describes the problem well, the same thing can happen horizontally, as can be seen at http://www.meyerweb.com/eric/css/edge/boxpunch/demo.html (look for the punchout on the right, the black border sticks out 1px) and on my defunct mozilla news page at http://grayrest.com/moz when the browser width is about 1024, changing the width causes this to fluctuate so if you don’t see it try changing the width of your browser.

  59. to the person who mentioned he had trouble getting list to be 14%:

    i have made a list which i use for vertical navigation. the list resides in a sidebar that is 20% of the body. here is my CSS for my list:
    ul.menu {
    width: 90%;
    list-style: none;
    margin: 0px auto 0px auto;
    padding: 0px;
    border: none;
    text-align: center;

    ul.menu li {
    text-align: left;
    margin-bottom: 2px;

    ul.menu li a {
    display: block;
    padding: 0px 0px 0px 1.5em;
    margin: 0px;
    border-left: 2px solid;
    border-right: 2px solid;
    width: 100%;

    ul.menu li>a {
    width: auto;

  60. Ok, first, I’m really liking the list+css combo for nav. However, I am having issues with inline lists. The one that is really bugging me is that there is a space between the list items that I cannot seem to get rid of when the list is inline.

    For instance, I have a list I’ve set to inline with each item having a border. There is a space between each item, outside of the border, of a couple of pixels. Is there a standard work around for this that anyone knows of?

  61. Love the article.
    When supplying a custom image for the bullet via list-style-image or list style, is it possible to set the vertical alignment of that bullet?

    Currently, the custom bullet bottom is aligned with the middle of the LI text. I would like to get them both valign=bottom.


  62. I think the design is very smart, but has just one flaw.

    We all have to write pages that look good in:
    a. browsers without css support (e.g. ipaq)
    b. browsers without javascript turned on (e.g. security bugs)
    c. browsers without proper dom2 support (e.g. netscape 4.x)
    d. browsers that support everything
    (For example, http://www.alforto.com, will display correct on all browsers.)

    Well, this design brakes on browsers with javascript turned off.

  63. elements can not be accessed because they are hidden in the css and there is no way to make these elements display.

    Oke, change .menu{ display: hidden into block and problem disappears. But now script is not working right the first time.
    A related problem is that an

      has no meaning with javascript, but without it has. It will try to load a html page.

      Has anybody a hint how to solve this problems?


  64. Fantastic article, and it really helped me in writing my own UL/LI DHTML menu article over at another site (email me if you want the link, don’t want to cross post on here :))

    Anyway, on a related note I have run across an odd little “bug” which I cannot find any references to sorting out on the web. So hopefully the brains around here could help (and spread the knowledge.) I hope this is suitable for this forum, if not please ignore.

    I have a UL/LI menu arrangement which works well but it relies on two images in the rollover sequence, an on and off effect. They are defined like so:

    background-image: url(../img/btn_arrw1_off.gif);
    background-position: 15px 6px;


    background-image: url(../img/btn_arrw1_on.gif);
    background-position: 15px 6px;

    The problem though is that they do not seem to pre-load properly. I inserted some pre-load script but to no avail. When I mouseover the LI items the images are pulled from the server, even the off image!

    However if I use JavaScript to swap the images then pre-loading works fine, but of course that just negates the whole beauty of the a:hover feature.

    Any help appreciated, ta 🙂

  65. An absolutely terrific article!

    I noticed the jumping, as well as Netscape drawing every other dividing line.

    1. To fixing jumping: remove borders, padding, etc.
    2. To fix the every other line problem, move the border from the bottom to the top. It does look a little different, but it works!

    #button li {
    border-top: 1px solid #90bade;
    margin: 0;

    See it in action on my site:

    I’ve tried it on Explorer 5.5, Netscape 7, and Opera 7 under Windows.


  66. I’m using a list item image that’s 10px wide (the fact that it is wider than a standard bullet might be important) .

    IE6 and M121 both render the list as expected using the margin-left AND padding-left rule described by eric meyer.

    So far so good.

    However, O7 fails to push the text to the right along with the added width of the image (over the standard bullet). I mention this because it looks fine with the standard bullet. In other words, Opera seems to have a “constant” padding between the image and the text, no matter what.

    This is the css I’m using:

    ul {
    margin-left: 19px;
    padding-left: 0;
    list-style-type: square;
    list-style-image: url(“../graphics/list01.gif”);}

    ul li {
    margin: 10px 0;}

    The ul is contained within the same div as the paragraphs. Evidently the div settings do not cause the problem.

    So…what should I do? I am DESPERATE!!! And yes, I have tried everything (short of uninstalling Opera… )

  67. I am trying to design two sites right now and I’d really like to NOT use tables for layout. My Graphic Designer has a tabbed design…I am trying to get close with CSS, but I can’t seem to figure out a good way to degrade on NS4? The majority of our audience is high school students, who seem to use NS4 (at least 70% of our hits at last check). I have server-side scripting at my disposal (ColdFusion), should I browser sniff and use alternate layouts? Any suggestions or links to help are greatly appreciated.

    BTW: Great article, this may be my new favorite site.

  68. Hey there. I tried to remove the left indent of a list as described under Positioning. I did it exactly as the article tells you to do. Looks fine in IE, but in Mozilla it doesn’t appear to be moving to the left. I am doing something wrong or is this just evil non-compliance? Please help me out 🙂

  69. hi, I choosed for using lists for some hyperlinks in my navigation menu, lists work fine with ie, but netscape and opera place the links on top of eachother… how comes ? my stylesheet page looks like this for the

      : ul.menulinks {
      list-style: none;
      margin-left: 1%;
      text-align: left;
      padding: 0;
      internet explorer gives each link on a different line, opera or netscape doesn’t…
  70. I googled here, which turned out to be exactly the right place, but I didn’t find my own issue addressed. I have a nav-menu which is a series of anchors in boxes, but the :hover background color only comes into play when the mouse is over the text, not when it’s over the trailing whitespace. It’s the same with this article’s menu.

    Can anyone think of a solution to make the entire box “hot”?

  71. Anyone fully knowledgeable on ASP, Databases, Web Design and CSS Stylesheets? And got some spare time on your hands? If so, email me at the address WEBMASTER@BLASTWAVE.ORG.UK – ANY contact will be greatly appreciated, so please get back to me.


    Orion – Webmaster :: blastwave.org.uk ::

  72. I am just a highschool senior, so my understanding of the syntax may not be uber high but:

    #button li {

    would it be more appropriate to tag it:

    #button ul li {

    My reasoning:
    1. Browsers stink – they may mess up with nested tags too often, which is a reality now and later – the li’s might be misinterpreted by a weak browser because they are not directly under the div
    2. I believe that references the items more specifically
    3. It would be consistent with the majority of the other hiarchel (sp?) designations in the article.

    Nit picking but hey 🙂 I liked the final example – that was one of the few good examples of css seperating style/content while using actual style.

  73. Typically a horizontal menu list has a pipe character (|) to separate items. This is mentioned in the list.

    I just wanted to suggest people look at using a colon (:) as a separator. The reason being that some screen-readers will pause in their translation when reaching a colon whereas a pipe character does not generate this action.

    So using a semi-colon provides better structure for screen readers.

  74. You’ve got padding being applied to an inline element.

    Modern (v6+) browsers will apply this padding, but will not alter the parent box of the inline element to add space for the extra padding.

    Basically vertical padding becomes useless.

    Which is why, if you want padding around your elements, you should set list items to display inline.

    Instead I recommend floating them with width set to auto. This works surprisingly well in legacy browsers. The only issue I’ve found with this is Opera 7 has some issues floating the list items while Opera 6 renders it perfectly. Go figure.

  75. Really liked the article.. Great job! I used it on a site for work and replaced a bunch of horrible
    ‘s and links. Time to scour for more great articles!

  76. I’m using the list style you mentioned here for a project I’m working on. Works great, except when I later set up bulleted lists to use a graphical bullet, the graphical bullet started also appearing to the left of my left navigation (happened on Windows, not Mac). Isn’t there a way to accomplish what you’ve described without hijacking other bulleted lists?

  77. Fantastic article. Its strange how css still manages to cause me so much grief though, – getting things to line up as you want. You have to be a freaken guru to make things work.

    It’d be great to see an online resource containing a bunch of navigation elements, from vertical, to horizontal, to tab-like, to multicoloured, to rollover effects etc etc… much like the multi-column layout resources.

    If I get anywhere I may even post it myself 🙂

    I really like how stopdesign.com does theirs, but there is a lot of css markup to make it look like that. I’d like something simpler.

  78. I’have been starting in writing HTML for a few weeks, and I explore the numerous web pages and sites exposing code, Javascript and so on. Thank you for the detailed lesson on lists, I’ll let you know what I have done with this. Thank you in advance, Jean-Marie, France

  79. Nice code, but when trying out the final blue block with full color styles, it jumps left on first mouseover of any of the buttons. I guess this wouldn’t be a problem if the whole thing was in another table, but just thought you should know. Maybe it’s centred on the page initially and your code is resetting it left justified?

  80. As there ist no discussion at the replace tables with CSS posting, i will post my question here. Up to now i have not found a solution for the vertical alignment problem without tables. Look:


    This code should generate this:
    + +
    + +
    + XXXX +
    + +
    + +
    But it generates this one:
    + XXXX +
    + +
    + +
    + +
    + +
    What shoud I Do?

    but it works with tables:


    if you past an answer please mail me a note, really would like to know how it works.

  81. Simply outstanding! Thanks for the blow-by-blow description, a necessity for ham-handed folks like me who really appreciate a detailed, in-depth discussion.

  82. Go to my website to see me trying to use the list idea. I’m okay with the fact that the neat bullet symbols won’t show up in IE.

    What I’m disturbed by is the way the background is on the sidebar with Opera 7. The background is supposed to extend all the way across the sidebar to a little bit away from the edge of the content. This problem isn’t in IE, for some reason.

    Also, “e-mail” in the sidebar is behaving in some very odd fashion. The word “mail” is in the next line as if there was some kind of line break between “e-” and “mail.” This problem, also, is not in IE.

    To be honest, those problems were there for Opera 7 even before I tried out the list thing. Even the “e-mail” problem. I used this as a way to be vaguely on-topic.

  83. when you have a{display:block} and you specify “height:1em”, then the divs are also active for the whole width in IE/Win.

  84. Another reason for using proper lists for a series of links is the W3C WAI requirement to have links separated by more than white space. This and the fact that they degrade nicely (enough) in early browsers are key issues.

    There is also a potential WAI issue about using graphics for bullets in that they will not be able to include alt tags, but I am not convinced this is really a problem as long as the graphics used don’t perform anything other than a purely aesthetic function.

    The IE6 jumping around thing seems to be quite common and I’m not sure if it is necessarily an indication of conflict in the css. It would be interesting to know if anyone has a definitive answer for this one, or is it just a bug in IE?
    Very useful article, thanks!

  85. What you created is simply amazing. I think many designers should do their best to avoid images and javascript where possible. I read your article and then used it for 300 items, imagine how long it would take to do them using images (300+300(onmouseover))!!

  86. In the specific case of a list of links that appear inline in a paragraph, what’s the point in defiling them as a list with

      and then using CSS to take away every aspect that makes such a list different than just putting the links in the paragraph? I am having trouble seeing where the advantage is.
  87. I’ve gotton the pure-CSS popup/hierarchical lists to work fine (in netscape 7) using ul/li, etc. However, the same approach fails when trying to use nested span’s instead of lists. I.e., the hover property doesn’t seem to stay set for the parent box when the mouse moves into the child “popup” box. It only works if thoses boxes happen to be lists/items.

  88. Mark Newhouse declares:

    “When using these characters, like », it is necessary to encode them as their escaped HEX equivalents.”

    This is false. In all levels of CSS, the right-pointing double angle quotation mark (U+00BB, “»”) may appear unescaped. As of CSS level 2, the only characters that require escaping when in a string are the string delimiters and control characters. Readers should obtain the details directly from the CSS specifications (a good start being http://www.w3.org/TR/CSS21/syndata.html ).

    Even when characters do require escaping, the escape does not have to be a hexadecimal number. The four characters


    form a perfectly legitimate CSS string, with the two middle characters representing one quotation mark (U+0022).

  89. Did anyone come up with a fix for the jumping problem in IE? What does M. Elford mean when he says “The menu system doesn’t jump when taken out of the ALA code framework”
    What would I have to do?
    This is a beautiful menu -thanks for the clean simplicity of the design!

  90. I am starting to develope my webpage which hopefully will include some freeware php scripts. I was just curious if anyone knew of any problems with validating pages with php scripts?

  91. I hope someone can help. I have set up a simple list of navigation links for my site – and I used the instructions presented here to make the list appear HORIZONTAL, instead of the default vertical. To do this, I simple used “display: inline”

    Now, each “

  92. ” is a link. To make the link active for the FULL WIDTH of the div, how can I do that? To do it with a VERTICAL, or default list, I’d simply use “display: block” But how do you make the link active for the full width on a horizontal list?

    Right now the link just works around the actual text. Each “

  93. ” has padding applied and also a rollover background color change.
  94. The “pipe” example does not seem to work in IE 5.0. The LIs get pushed together, e.g.

    instead of
    item1 item2 item3 item4

    IE 5.0 ignores horizontal padding applied to LIs, as well as horizontal margins.

    Anyone know how to work around this?

  95. wow, excellent solution and I really liked the real world example…
    Thanks for showing an easy to do something that I’ve doing using table for years.

  96. I don’t know if this fixes the IE 5.0 bug (I suspect it doesn’t), but there is a simpler way to make an inline menu:

    #nav {background-color:green;padding:10px 0px}

    #nav a {text-decoration:none;color:#fff;padding:10px 15px}

    #nav a:hover {background-color:red}


  97. Any way to get nested lists to validate? Or a CSS alternative that doesn’t just put an indent between the disc and the test for that line?

  98. Thanks for the article. Its time I ventured into this scary area of web design once and for all.

  99. At http://www.normandale.edu/next/ I’m developing a slightly more complex version of the ul/li dropdown menu, starting from the http://www.gazingus.org/html/menuDropdown.html code.

    On IE5/Mac, the gazingus code works wonderfully (apart from that few-px offset bug.) My code, on the other hand, initally displays those top-level inline li elements on top of each other, suggesting that they’re displaying as block. Once you mouseover, they wind up inline.

    The menu offset is also very screwy, and there are a few other things …

    My main concern is the non-inline initial rendering. Has anyone else seen this? Fixed it?

  100. I am completely converted. This is a great article! Glad I Googled-it up. My question though it with orderted lists. My navigation menu follows essentially an outline structure.

    I’d like the make the ordered list appear exactly as you have it in your example (which the a:link to a:hover rollover effect). The problem is with an ordered list the number (or letter) preceding the menu label is outside the box that’s affected by the rollover.

    The box model for the label doesn’t seem to include the number part of the it for some reason. This seems to be by design. I suppose I could do an un-ordered list and put the number inside the box. But there are text-wrapping drawbacks to that and besides, you were so convincing about proper markup I just don’t want to do that!

    Any ideas – or a clue as to what I am even talking about? 🙂

  101. I swear I once saw a way to alternate colors for iterative items (lists, table rows) with CSS – I think it had something to do with using a counter(), but am not 100% sure. Has anyone seen this trick?

  102. Just thought you’d all like to know about a bug I’ve run into:

    In IE6 (at least on XP) if you use a UL for links or such, and you specify padding for the UL or any of its children, you end up with the whole thing being larger than it should be – for example if it’s a link list in a div that you’re using for a navbar, and you set a width for the div, the div will end up being larger than you specified by the amount of padding specified in the children.

  103. A few lines of that CSS code were Greek to me, but other than that I really learned a lot. As a “designer” who likes everything pretty AND a “coder” who likes everything slim and clean, this artcle was able to quiet the voices in my head for a moment or two. I now feel that both sides of my brain have a chance at shaking hands in the near future and solving many layout issues.

  104. A great article, one I will definately bookmark and use elements from. But I still think that when I really want my navigation to work in all browsers, and look the same in Netscape or IE, or if the positioning is important, and must line up with element in the background image or rest of the page, good ol’ fashioned tables, javascript and blank gifs are the answer. CSS still seems to flakey and browser-specific as most of the responses here seem to prove, what with missing divider lines, vertical rounding errors and positions changing!

  105. I am finding the transition to css extremely frustrating … so I was please to come across this article. However, the layouts that my desginers come up with are slightly more complex than the real world example you demo’d.

    Looking at the example, I was wondering how one would add bullets and keep an alternating background color for each row (list item)? When I add bullets, the background color stops just before the bulllet. Also, you simply set a single-pixel solid border as a divider between items. However, my designers like to use single-pixel-dotted-lines between rows, so how does one go about coding for that? Is it possible to specify an image for a border style?


  106. I find that the hover effect is slow in IE6 compared to Opera.
    Is this correct and can something be done to make it faster?

    Thank you,


  107. I read the article and it the cogs spinning, the pipe example especially since I use similar formatting for most of my menus in web apps I build for my clients. The pipe example works great for 90% of those menus, but there are a few I need to have the menu be the width of the page and not wrap if the user resizes the window. Additionally I am creating this list on the fly from a db and so I cannot put a width static width in the li. I currently have to use a table with the width=100% using nowrap in the cells to achive this. Has anyone else done this? Or is this just not currently possible?


  108. Normandale Community College ( http://www.normandale.edu ) just put the horizontal li nav into practice as part of a XHTML/CSS redesign. IE5 Mac and Opera begged to be excused, but everything else is happy.

    One more thing: Eric Meyer’s recent redesign reminded me of the wisdom of putting one’s lengthy navigation _after_ one’s content … thus the site’s nav menu gets included at the end of the XHTML, but is visually positioned at the top.

    Beautifully simple trickery, this.

  109. Does any know how to create a sub list in a different style that works for both IE and NS/Mozilla

    • link1
      • sublink

    I’ve manage fine with IE.
    Example #menu li li a:

    Any ideas

  110. Being relatively new to this approach with CSS a few things confuse me. First of all, what the heck are the shortcuts for the hex colors? I can figure out #000 and #fff, but where do you find all the rules pertaining this formula for specifying hex color values?

    Secondly, I’m so used to measuring everything in pixels, I cannot relate to the em unit of measure. How can you possibly, get things lined up accurately using that unit of measure?

    What’s the difference between margins and padding? Is that like the difference between cellspacing and cellpadding?

    In the #button style, the padding is specified as such:

    padding: 0 0 1em 0;

    I’m assuming those are left, right, top, bottom?

    I’d appreciate any feedback. This stuff is really great!

  111. I’m designing a new site and intrested in using CSS for the menus and very intrested while reading the article. Once thing I noticed thats not covered are sub menus.

    In my case I want to have vertical menus that when hovered over, open a sub menu to the right. Is this possible ?


  112. Well I’ve come to all this late and am on a steep learning curve.

    I’m trying to tame a nested list for use as a menu. Basically I don’t want any indent, I do want each menu item in a box, and I do want to be able to control the background and font colours, according to the level.

    Taming the automatic indenting and ‘leading’ seems to be a real challenge, and there seem to be all sorts of variations between Mozilla and IE6. Has anyone done this and have an example. I can get what I want with tags for the top level items and

      for the second level. but I want to be able to scale to three or four levels.
  113. I’m busy boning up on CSS and your site is a revelation. I just took this page on Taming Lists and the menu you prepared in that page is great. By coincidence the colour scheme and so on were already perfect.

    I will now be working on enhancing my own site to your standards.


  114. Great article! It’s hard to find really good CSS tutorials on the internet that go beyond the basics, yet still consider real-world browser compatibility issues. Anyway, this article really has me thinking a bit different now about some of my HTML/CSS structures.

  115. I really liked the article you have put out. I am having problems with my menu though. When I make this menu, in IE there is big space on the left hand side of the menu. In NS this doesn’t happen. How did you fix this problem on your pages, they look fine?
    I tried to move the menu to the left with the CSS “margin-left: -16” but this would cause it to be hidden partially in NS. Any suggestions?

  116. I really liked the article you have put out. I am having problems with my menu though. When I make this menu, in IE there is big space on the left hand side of the menu. In NS this doesn’t happen. How did you fix this problem on your pages, they look fine?
    I tried to move the menu to the left with the CSS “margin-left: -16” but this would cause it to be hidden partially in NS. Any suggestions?

  117. Try ditching the li / ul list-style image in place of attaching a background image using no repeat :

    background-image: url(../bullet.gif);
    background-position: left;
    background-repeat: no-repeat;

    remember to turn off the li display – use outside and voila you get to control the distance between bullet and the start of list contents.

  118. I have placed the following code in my CSS:

    background-image: url(../bullet.gif);
    background-position: left;
    background-repeat: no-repeat;

    I still have the same problem.
    I am not so familiar with the CSS to understand what you mean by ditching the ul/li and how do I “turn off the li display”?

    Could you please explain more in detail?

    Here is what I have in my CSS pertaining to the menu:

    #leftnav {
    width: 10em;
    border-right: 1px solid #000;
    padding: 0 0 0em 0;
    margin-bottom: 0em;
    font-family: ‘Trebuchet MS’, ‘Lucida Grande’,
    Verdana, Lucida, Geneva, Helvetica,
    Arial, sans-serif;
    background-color: #0e3061;
    color: #333;

    #leftnav ul {
    margin: 0; /*removes indent IE and Opera*/
    padding: 0; /*removes indent Mozilla and NN7*/
    list-style-type: none; /*turns off display of bullet*/
    background-image: url(../bullet.gif);
    background-position: left;
    background-repeat: no-repeat;
    border: none;
    font-family: ‘Trebuchet MS’, ‘Lucida Grande’,
    Verdana, Lucida, Geneva, Helvetica,
    Arial, sans-serif;
    font-size: 10px;

    #leftnav li {
    border-bottom: 1px solid #4A6D9B;
    margin-left: 0;

    #leftnav li a {
    display: block;
    padding: 5px 5px 5px 0.5em;
    border-left: 10px solid #21497e;
    border-right: 2px solid #21497e;
    background-color: #0e3061;
    background-image: url(../Graphics/LeftBtn_Blank.gif); /* */
    background-position: 0px 0px;
    color: #fff;
    text-decoration: none;
    width: 100%;

    html>body #leftnav li a {
    width: auto;

    #leftnav li a:hover {
    border-left: 10px solid #0e3061;
    border-right: 2px solid #0e3061;
    background-color: #21497e;
    color: #fff;
    #currentlink a:link, #currentlink a:visited, #currentlink a:hover {
    border-left: 10px solid #0e3061;
    border-right: 2px solid #0e3061;
    background-color: #21497e;
    color: #fff;

  119. I’ve created a navigation menu based on the examples found in this article, but unlike the example I wanted to leave the list style to include the bullet. Unfortunately, IE6 is placing the bullet on the second line of any links that wrap to the next line. This is due to the display:block; width: 100% bug fix for IE.

    Anyone else experiening this or know a fix?

  120. i am trying very hard to understand everything about CSS styling… and it is kind of tricky because there is way too many HACKS to consider..

    however zeldman + friends or friends + zeldman are right… let’s follow webstandards and hopefully it will be better on the web.

    oh.. i forgot… my question…
    y’see i am trying to make a menu (a

  121. menu) and i would like to have a background-image inside the
  122. that will swop when you mouse-over it… but i cannot make this happen.. i tried the menu recipe over at Project VII but that is not a listmenu.. is there a way to do this or is it impossible?


  123. Has anyone solved the problem of using style classes to create multiple nested lists having DIFFERENT list-style-types within one doc? Example:

    followed in the same doc by:

    That is, I want to have 2 different nested-list classes, used interchangeably in a single doc.

  124. The followiung CSS definitions will allow 2 different nested list styles in one doc. Just put the list inside a DIV or SPAN with the desired class. No need to re-specify the class on each OL tag in the doc, just in the STYLE definition.
    .num OL {list-style-type: decimal; }
    .num OL OL {list-style-type: lower-alpha; }
    .num OL OL OL {list-style-type: lower-roman; }

    .roman OL {list-style-type: upper-roman; }
    .roman OL OL {list-style-type: upper-alpha; }
    .roman OL OL OL {list-style-type: decimal; }
    .roman OL OL OL OL {list-style-type: lower-alpha; }
    .roman OL OL OL OL OL {list-style-type: lower-roman; }

  125. hey – i’m having slight problems with the horizontal list trick – i made one with the pipe thing as a navigation bar, and it all looks fine, but the problem I have is that I want it to wrap correctly. The way i did it was to use “a { white-space: nowrap; }” so that the links stayed together, but i am getting different behaviour between ie6 and moz1.4…

    take a look here: http://www.dannypoo.co.uk/herbawohl/inline.htm

    my problem is with the vertical lines, where if you shrink the navigation bar so that it wraps (something which will no doubt happen often as it’s quite wide).

    as you will see if you use mozilla, everything works as it should, with the horizontal line retaining its padding from the text as it wraps to the next line. problem with IE is that it seems to include the end of the previous line in with the padding for the wrapped list element.

    can someone help, cos this is driving me crazy!!!



  126. I’ve got a ul that I’m using for my left nav. Instead of using text, I’m using images as the nav elements. Within the li elements, IE6 keeps adding 4px space between the images. It works fine in other browsers and on a Mac. Anyone else seen this? Is there a fix? I tried copying and pasting the styles directly from the great article and thing were fine. Then I added an img and IE6 added the 4px space below it. Any suggestions?


  127. Hi, does anyone read this far?

    Anyway, I notice with my custom bullets that on IE6/Win sometimes the bullets don’t get rendered. I’ve tried this with custom bullets (12×12 gifs), and I’ve also redone it all using the same gifs but as background images instead.
    Either way seems to produce the problem.

    Is this a known IE bug, or is it my code perhaps? It’s pretty intermittent, I can’t guarantee reproducing it. So maybe it’s also dependant on the system memory or capabilities?

    Great article by the way!


  128. I notice in this article that the inline list items are always assigned a margin. They are never flush together in Mozilla 1.4 and Mozilla Firebird 0.6.1.

    Why is that, and how can I get the list items to be flush. Even in the example the margins are set to 0px.

    Thanks! Great article.

  129. Anyway of making the button bgcolour staying on when clicked? And only having the last button clicked retain the new background colour value?

  130. Tim, maybe that should be done in HTML. Change the class of the “clicked” button, and be sure to make that class have the color you want.

  131. There’s a wonderfully gruesome bug in Mac IE 5.2 that makes working with inline lists and the border-pipe trick very annoying. It appears you cannot completely text-align:center or text-align:right an inline list. If you do, you will see the list elements centered but when you access anything like border values they are still aligned left! Now that’s some sloppy programming if they’re hacking up block elements like that, avoiding encapsulation. This was a very hard bug to track down but 2 hours later I figured it out so beware. Win IE 6 handles ok, haven’t tested in earlier Win IEs. You can workaround by applying a padding-left but you can’t really get it centered that way if the list is on two lines.

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA