87

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 (note 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?

2
  • 3
    I like where you're going with this. The more you can keep intact the data structure that your document represents, the more you take advantage of the power of CSS. As always, though, you have to be aware of the fact that older browsers won't understand the content property. Commented Oct 4, 2009 at 20:05
  • I found solution without additional rules and IE8 support Commented Aug 16, 2012 at 12:58

6 Answers 6

87

To remove the trailing comma, use the :last-child pseudo-class, like so:

#taglist li:last-child:after {
    content: "";
}
Sign up to request clarification or add additional context in comments.

4 Comments

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: quirksmode.org/css/contents.html )
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.
Awesome. Thanks a lot. This solution works fine on Mac OS X in Safari 4.0.3 and FireFox 3.5.2.
:last-child not supported in IE8, use :first-child selector instead, or just use mine solution
34

Replace one your rule

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

with just another one

#taglist li + li:before {
    content: ", ";
}

Pros:

  • One rule do all the work.
  • No rules for cancel previous rule,
  • IE8 Support

3 Comments

This is pretty smart, but as far as I can tell it requires additional logic or altered HTML to remove the spaces that appear before every list item because there is whitespace between the li nodes.
@Jakob OH yeas. Shame on me. There is only one requirement to have float: left for list items.
Clever, but I don't like it. This behaves poorly if your line wraps.
29

It's easy with CSS3 you can use pseudo selector last-child and not at once:

ul#taglist li:not(:last-child):after {
  content: ", ";
}

Check results here https://jsfiddle.net/vpd4bnq1/

Comments

6

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.

2 Comments

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 I made the same with only one rule with + selector =)
0

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

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

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

This requires having the last item in your list tagged with a class attribute value of “last”:

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

Comments

-1

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.

1 Comment

solution became cross-browser compatible starting from IE8, if you will use + selector instead of :last-child one, and before instead :after

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.