How to add a divider between menu items in css using only one selector

A popular way for dividing between menu items, or elements in general is the single border.

li { border-right: 1px solid #000000; }

The problem with doing that is how do you not have the border after the last element?

One solution is to add a border to all of the list-items then remove it from the last one:

li:last { border-right: none }

But this solution is not elegant. It get’s the job done, but it adds an extra line of code. So what can we do?

This is where the CSS Adjacent Sibling Combinator (a.k.a. the plus sign) or the CSS General Sibling Combinator (a.k.a. the title) come in handy.

The CSS Adjacent Sibling Combinator

This will target a specified element that is adjacent, in the DOM tree, to another specified element as long as they share the same parent and first sequence immediately precedes the second one.

For example, if you would like to style every h3 element that is adjacent to an h1 element white you’d do this:

The HTML markup would be:

<hgroup>
    <h1>Title</h1>
    <h3>Tagline</h3>
</hgroup>

The CSS to target the h3 tag would be:

h1+h3 { color: white; }

Though, if you tried targeting the h1 tag like this:

h3+h1 { color: white; }

It wouldn’t work because the h3 tag does not precede the h1 tag in the HTML markup.

Or if you had an h2 tag in between the two elements, the style also would not be applied to the h3 tag…

<hgroup>
    <h1>Title</h1>
    <h2>Secondary Title</h2>
    <h3>Tagline</h3>
</hgroup>

because the tags are not adjacent to each other.

The CSS General Sibling Combinator

Now let’s say you DO want the style to apply in the example above?

The General Sibling Combinator will target a specified element that is a sibling under the same parent element of another specified element even if they are not next to each other as long as the first specified element precedes the second one.

Meaning that in the second html example we could apply a style to the h3 tag using the following code:

h1~h3 { color: white; }

Even thought the h1 and h3 are not adjacent to each other, since they are still siblings, the style would be applied to the h3 element.

However if you tried the following:

h3~h1 { color: white; }

The style would not be applied.

Using the Sibling Combinators to Solve Our Problem

Back to the menu problem. How do we add a border in between each menu-item, but only use one line of code to style it?

li+li { border-left: 1px solid #000000 }

i.e. Every list-item that comes right after another list-item should have a border to it’s left.

Or you could do this:

li~li { border-left: 1px solid #000000 }

Which basically means that every list-item that has somewhere, under the same parent, another list-item before it, that list-item should get a border to it’s left.

Voilà! There you have it!

Gaming the Sibling Combinators

Lea Verou uses this technique used to create an actual game of Tic-Tac-Toe in pure CSS. The only Javascript used to make the game functional is for setting up the board. Aside from that, the conditions used to monitor the game use the Sibling Combinators. When I first saw this I printed out the stylesheet to read on the bus home. It’s a brilliant use of CSS and I have to admit that I’m jealous that I didn’t think of it first.

Feedback

Have you seen the Sibling Combinators used elsewhere? Have you seen another elegant solution for the border in a menu? Please share below.


    40 thoughts on “How to add a divider between menu items in css using only one selector

    1. Thanks for this. I was adding left borders to all of the li elements in my menu, then using li:first-child to remove the border from the first one. That way works, too, but your way is better because it only requires one rule to be written.

    2. great …..but how can we define …how far the divider should be…my navigation is horizontal..when i try to give padding or margin…divider is not visible..its gone… plz let me know how can i difine the distance or…aling center divider..between two text…

    3. The idea would be to use padding and margin. If the divider is gone than something else is happening there. If you can point me to your site I’ll be happy to suggest something for you.

    4. Thank you very much for this. Fought with trying to implement this a variety of different ways and this was a very simple and clean solution.

    5. Awesome tips! Question, though – can you change the height of those separators? When I put them in, they are quite tall. I’d like them to only be as tall as the words in the nav bar. Thank you!

    6. There is a problem with this “solutions”.
      Since you have to give a padding-left of 5px to even out the space between divider it shows on the first li.

      1. This was designed for a menu floating right. You can apply the padding to all but the first (or last) item using the same technique as is used for adding the border.

    7. Thanks for providing such a great tip.
      I’m wondering how it can be used in case of dropdown navigation?

      Using li+li will apply border rule to dropdown/subitems as well.

      1. Great question!

        You want to use the css child selector > for that.

        If the top level UL has an id of #nav the code would be #nav > li + li.

        This targets only the direct children of #nav.

    8. li+li {
      background: url(“http://site.com/images/css/pipeline.png”) no-repeat left;
      }

      Use tranparant png file and ur free to use every image on any height bij styling the image, seems to work fine

      I know nothing, peace!

    9. Hi
      I can’t see any anyone confirm how to add any other character (I dont want a border/pipe line, but a full point or forward slash etc) to a nav menu. Please can you help?

    10. Thanks! Its really helpful. But i have a question. How can i use vertical gradient in those dividers? Please help…….

    Leave a Reply