10

I'm trying to find a simple method of getting all the links spread evenly over the horizontal navigation. This would be very easy if it would be a fixed amount of links, but they will be dynamic.

So it could be either 5 or 10 links, nobody knows. Despite the amount of links I would like them to spread evenly across the navigation without using a table.

The reason I don't want to use a table is because it will break the UL LI structure which is (apparently) considered the way to go when building a navigation (SEO).

Here's a jsFiddle explaining it more in depth: http://jsfiddle.net/pkK8C/19/

Looking for the most light method.

Thank you in advance.

Rick Kuipers
  • 6,616
  • 2
  • 17
  • 37
  • so you want to fit as many navigational items within 400px or the width wont matter? I can say that you may need to use Javascript to achieve that. – Jaspreet Chahal Feb 20 '12 at 23:39
  • @JaspreetChahal Yep, I kinda figured that... still wouldn't really know how to do it, is there a way to calculate the width of a word in js? Or would we have to simulate it in an invisible div and take the width of that div... – Rick Kuipers Feb 20 '12 at 23:43
  • Well for me you will need to have a some hard limits on outer element and then render your Inner elements. Here is a good post that you can read on getting text widths http://stackoverflow.com/questions/118241/calculate-text-width-with-javascript in js. here is something that I did in jsfiddle http://jsfiddle.net/pkK8C/27/ but that wont accomodate if you links exceeds certain limit – Jaspreet Chahal Feb 20 '12 at 23:52
  • Thanks for your help, but I'm going to go with Marat Tanalin's solution. :) – Rick Kuipers Feb 20 '12 at 23:52

4 Answers4

8

Old browser might be a headache, but it works for new ones:

div#navigation ul {
    list-style-type:none;
    height:30px;
    text-align:center;
    width: 100%;      /* new */
    display: table;   /* updated */
}

div#navigation ul li {        
    margin-left:50px;
    display: table-cell;  /* updated */  
}
Dmitry Nogin
  • 3,670
  • 1
  • 19
  • 35
  • The compatibility was bothering me but since Marat Tanalin pointed me to display-table.htc I will accept his answer. +1 from me for the code example. – Rick Kuipers Feb 20 '12 at 23:51
8

Use display: table for UL and display: table-cell for LI. And display-table.htc for IE6/7 if they matter.

Marat Tanalin
  • 13,927
  • 1
  • 36
  • 52
  • 3
    For this to work, I believe the width of the UL has to be set to 100% (i.e. width: 100%) – Prabu Oct 28 '13 at 10:44
  • @pwee167 That's quite obvious. ;-) – Marat Tanalin Oct 28 '13 at 13:05
  • I find that using `max-width` CSS attribute for 1st level `LI` elements can be handy if the first column contains only short texts and the other ones have longer link texts. Modern browsers seem work. – sampoh Nov 20 '13 at 15:09
3

Here is a jQuery solution which evenly spreads the links to 100% of the confining element. Leftmost and Rightmost links are butted up to the ends.

jQuery:

pad_menu() increases padding until the last li floats below the first then decreases padding by one, so the last li is back on the same line. var i stops infinite loop (which should never happen anyhow).

  $(document).ready(function(){
    pad_menu();
  });

  function pad_menu() {
    var i = 0;
    var pos_first;
    var pos_last;
    var pad = $('#menu li').css('padding-left').replace(/[px]/, '');

    do {
      pad++;
      $('#menu li').css('padding-left', pad);
      $('#menu .first-item').css('padding-left', 0);
      $('#menu .last-item').css('padding-left', 0);
      pos_first = $('#menu .first-item').position();
      pos_last = $('#menu .last-item').position();
    } while (pos_first.top == pos_last.top && ++i < 100)
    $('#menu li').css('padding-left', pad-1);
    $('#menu li.first-item').css('padding-left', 0);
    $('#menu li.last-item').css('padding-left', 0);
  }

HTML & CSS:

ul#menu li {
display: inline;
float: none;
padding: 5px 0px 5px 20px;
}
ul#menu li.first-item, ul#menu li.last-item {
padding-left: 0px;
}

<ul id='menu' class='cols'>
  <li class='first-item'><a href='page1.html'>Page 1</a>
  <li><a href='page2.html'>Page 2</a></li>
  <li><a href='page3.html'>Page 3</a></li>
  <li><a href='page4.html'>Page 4</a></li>
  <li><a href='page5.html'>Page 5</a></li>
  <li><a href='page6.html'>Page 6</a></li>
  <li><a href='page7.html'>Page 7</a></li></a></li>
  <li class='last-item'></li>
</ul>
Anthony Scaife
  • 564
  • 5
  • 15
2

There's a nicer solution here, where you use text-align:justify:

How do I *really* justify a horizontal menu in HTML+CSS?

Read the accepted answer carefully though, the following caveats apply:

  • Spaces in your LI text need to be replaced with &ensp; or they'll be counted as spaces between your logical items (&nbsp; doesn't work)
  • You need to have whitespace in your HTML between your LIs (can be a gotcha if you're generating them in a PHP loop.
Community
  • 1
  • 1
Jeremy Warne
  • 3,437
  • 2
  • 30
  • 28