tags:

views:

461

answers:

4

I'm looking for a way to style an unordered list in XHTML with CSS such that it is rendered inline and the list items are separated by commas.

For example, the following list should be rendered as apple, orange, banana (not the missing comma at the end of the list).

<ul id="taglist">
  <li>apple</li>
  <li>orange</li>
  <li>banana</li>
</ul>

Currently, I'm using the following CSS for styling this list, which almost does what I want, but renders the list as: apple, orange, banana, (note the trailing comma after banana).

#taglist {
  display: inline;
  list-style: none;
}

#taglist li {
  display: inline;
}

#taglist li:after {
  content: ", ";
}

Is there a way to solve this problem with pure CSS?

+3  A: 

Try using the last-child pseudo-class like so:

#taglist li:last-child:after {
    content: ""
}
Jakob
This is certainly the easiest way, but `last-child` is even less-well implemented than `first-child`, though it depends on the usage of the site and can be compensated for with JS/jQuery, conditional comments for IE etc. ( reference: http://www.quirksmode.org/css/contents.html )
David Thomas
I don't have data on this, but I was under the impression that browsers that don't implement `first-child` and `last-child` don't implement `before`, `after`, and `content` to begin with.
Jakob
Awesome. Thanks a lot. This solution works fine on Mac OS X in Safari 4.0.3 and FireFox 3.5.2.
SwedishChef
+2  A: 

It depends on browser implementation, but this should work. Though it relies on first-child, which may limit its use, but essentially puts the comma-space ", " before the list-item, rather than after. I'm not sure how padding/margins will affect this, but if you use `display: inline; with margins and padding set to zero, it should be okay.

#taglist li:before {content: ", ";}
#taglist first-child {content: ""; } /* empty string */


Edited: to respond to corrections offered in comments by Jakob.

The following works (demo page here: http://davidrhysthomas.co.uk/so/liststyles.html:

#taglist {width: 50%;
  margin: 1em auto;
  padding: 0;
  }

li  {display: inline;
  margin: 0;
  padding: 0;
  }

li:before {content: ", ";
  }

#taglist li:first-child:before
  {content: "";
  }

Although the commas are strangely floating-in-the-middle-of-nowhere, and, honestly, I prefer the accepted answer anyway. But just so's I wasn't leaving a horribly broken answer lying around, I thought I should fix it.

Thanks, Jakob.

David Thomas
Actually, this won't work. `first-child` is a pseudo-class, so it has to follow an element (`li` in this case), and to get the desired result it must also be followed by `:before`, like so: `#taglist li:first-child:before { content: "" }`.
Jakob
A: 

There is no pure css way to do it that's cross-browser compatible ( thanks to Microsoft ). I suggest you just do it with server-side logic.

You can probably get close with using a last class on the last li and using background images for all lis but the last, but you will not be able to do :last-child and content: in IEs.

meder
+2  A: 

This is the way that the guys at A List Apart recomend in their article "Taming Lists":

#taglist ul li:after {
     content: ",";
     }

    #taglist ul li.last:after {
     content: "";
     }

This involves having the last item in your list tagged with a class atribute value of "last".

Jamie Dixon