1

I have searched long and hard for this one and can't seem to find a solution.

I have a client who wants the menu text to use 100% of the width of the menu and have each menu item spaced out evenly. In other words, the left-most menu item should sit flush with the left side of the <nav> and the right-most menu item should sit flush with the right side of the <nav>.

I would normally set the <li> to text-align:center;, but that leaves space on the left side and the right side. Is there a way to accomplish this with just CSS and HTML? In my version, the left side is fine, but there is space on the right. Here is my code:

HTML:

<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Media</a></li>
<li><a href="#">Tour</a></li>
<li><a href="#">News</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>

CSS:

nav ul{
display: table;
table-layout: fixed;
width: 100%;
padding: 0;
100px;
}
nav ul li {
list-style-type: none;
display: table-cell;
background: gray;
}
nav ul li a {
display:block;
}

And a fiddle with the exact same thing: http://jsfiddle.net/zx4de/1/

Any help would be much appreciated. Thanks!

360zen
  • 25
  • 6

3 Answers3

5

Instead of using table layourt, you can make the elements inline-block and use text-align: justify:

nav ul{
    width: 100%;
    padding: 0;
    100px;
    text-align: justify;
    background: gray;
}
nav ul li {
    list-style-type: none;
    display: inline-block;
}

Add a small trick to make it actually fill out the line:

nav ul:after {
    content: "";
    display: inline-block;
    width: 100%;
}

The results:

http://jsfiddle.net/zx4de/3/

[edit] As per comments: The problem with this approach is that the container (nav>ul) will contain two lines of text. :after enforces this, and is actually needed to make the justify work (because the last line of a paragraph isn't justified).

Specifying a height of 0 for the ul:after doesn't work, since it doesn't affect the line height of that second line, only the line height of (a part of) the content of the second line.

So, there are a couple of ways to work around this:

  1. Specify an exact height for the ul element. If you know your line height, you can make the ul that height (for instance 1.3em).

    Like this: http://jsfiddle.net/zx4de/9/

  2. Play with the font size. If the ul doesn't have an explicit, absolute line height, then setting the ul{font-size} to 0will make its text content collapse and make the line height 0. Then, you can specify a differentfont-sizefor theli` elements inside, to make them show the proper height. The advantage, is that you don't need to know the line height, although you do need to know the font size you want to have for the items. But I can imagine that this information is already know, since the font-size will probably be part of your design.

    Like this: http://jsfiddle.net/zx4de/8/

Community
  • 1
  • 1
GolezTrol
  • 114,394
  • 18
  • 182
  • 210
  • This is probably the best solution in here. Certainly the most dynamic, you can add any number of LI's to the nav without having to modify your CSS. – Michael Apr 09 '14 at 20:22
  • Indeed. The 'disadvantage' is that the space between the texts doesn't belong to any of the links, but actually I think that is better. In the other solutions, the grey area is clickable, but it is not clear to which of the links the area belongs, and even if you make it clear, it is still quite arbitrary. – GolezTrol Apr 09 '14 at 20:24
  • Think it was a nice answer to a nice question... I wish I understood how it worked... – benomatis Apr 09 '14 at 20:27
  • I really like this answer. It is soooo close to what I need. I just wonder if there's any way to get rid of the tiny space to the right of the last li. When the menu is larger, it is slightly more noticeable (especially to picky graphic designers;). – 360zen Apr 09 '14 at 21:22
  • There is actually one more question about this solution. Why does the `ul:after` CSS cause the menu height to double, even when height is set to 0? – 360zen Apr 09 '14 at 21:32
  • You're right. The `:after` causes the content the become two lines (which is needed for `justify` to work). Setting the height doesn't change that. To get around that, you either need to set the height of the `ul` element, or play around with the font-size/line-height. I've updated the answer with two examples, although there may be other workarounds as well. – GolezTrol Apr 10 '14 at 14:16
1

Try this one out:

nav ul li {
    list-style-type: none;
    display: inline-block;
    background: gray;
    width: 20%;
}

nav ul li a {
    display:block;
    text-align:center;
}

nav ul li:first-child,
nav ul li:last-child{
  width: 10%;
}

nav ul li:first-child a {
    text-align:left;
}

nav ul li:last-child a {
    text-align:right;
}

here is the codepen if you are interested : http://codepen.io/nighrage/pen/uhLIz/

ramesh
  • 2,296
  • 4
  • 19
  • 29
  • A good answer, so you get a +1 from me. Unfortunately not as dynamic as GolezTrol's answer. Add a 7th item to the menu then suddenly you have to re-calculate all the percentages etc. – Michael Apr 09 '14 at 20:24
  • Golez definitely had the better answer, he got a +1 from me. :D You learn something new everyday. – ramesh Apr 09 '14 at 21:01
  • I like that this one actually goes ALL THE WAY to the edges, but there seems to be more space between the 1st and 2nd item than the 2nd and 3rd... – 360zen Apr 09 '14 at 21:21
  • you can play around with the values until you find the perfect balance, you could try 19.75% for the li elements and 10.5% for the first-child and the last-child. Seem to be alright. If you are looking for responsive design, it looks pretty good on tablet as well. – ramesh Apr 09 '14 at 22:24
-1

With your fiddle:

Simply add text-align: center; to the a-tag instead of the li-tag.

Pim
  • 756
  • 1
  • 7
  • 18
  • how will that pull the leftmost to the left and the rightmost to the right keeping the same distance between the items...? – benomatis Apr 09 '14 at 20:26
  • In his fiddle, the display properties set on ul and li take care of that. I believe this is all the OP is asking, or I must have misunderstood the question. – Pim Apr 09 '14 at 20:28