views:

337

answers:

2

I'm trying to put to gether a navigation bar using a table:

  • There are n links to different parts of the website
  • There is one "logout" link, which is an icon of fixed size

What I'd like to do is the following. The available width for the whole bar (which is known in advance) minus the required width of the icon should be divided equally among the cells containing the n links for navigation (ignoring the size of the links inside, this is not a problem).

Currently, I'm performing this computation in PHP and use to achieve this. However, this does not comply with the XHTML 1.0 Strict standards. According to the W3C validator, I should use CSS to set the width of the column. Problem is: I don't know how to do this, and if it is at all possible. Probably this problem is a hint that I shouldn't be using tables for this, but I have no other ideas at the time.

How can I achieve the effect, using tables or something else, in an XHTML Strict and CSS compliant way? Thanks for any ideas.

+1  A: 

The easiest way would be to put the links into little boxes (all the same size). Since CSS has no way to make calculations, you must still set the width of the boxes but by using CSS, you can do this once. Use DIV for the boxes. The class for the boxes must say display: inline; so they behave like words in text (the browser will place them next to each other on a line).

After that, you just calculate the width per box in PHP and send this width in a little piece of inline CSS in the header of the HTML page. That way, all boxes will have the same width and they will all be in the same line.

For an example how to create a navigation bar with CSS, look at the source code of the page you're reading just now.

Aaron Digulla
Seems elegant. Apart from getting rid of the tables, this boils down to the "PHP-generated CSS" I had in mind. The "display: inline" allows me to ditch a lot more "fake tables". Thanks.
Martijn
You'll have problems with spaces (" " not gaps) between the elements with `display: inline`. My solution avoids this potential problem.
Eric
Thanks, I'll be sure to pay attention to that!
Martijn
+2  A: 

First off, scrap the tables. Your links are not tabular data.

Basics

Start off with this:

CSS

ul.navbar
{
    padding-right: 25px;
    list-style:none;
}
ul.navbar li
{
    margin: 0px;
    padding: 0px;
    border: 0px;
    display: block;
    float: left;
}

ul.navbar li.icon
{
    margin-right: -25px;
    width: 25px;
    float:right
}

HTML

<ul class="navbar">
    <li>Home</li>
    <li>FAQ</li>
    <li>Contact</li>

    <li class="icon"></li>
</ul>

Equal width

The icon li should be hugging the right edge. Now, there are a few ways you can acheive the equal spacing. One way would be to have these classes, and apply them to the ul, with either php or jquery:

CSS

ul.navbar.links1 li
{
    width:100%;
}

ul.navbar.links2 li
{
    width:50%;
}

ul.navbar.links3 li
{
    width:33%;
}

ul.navbar.links4 li
{
    width:25%;
}

ul.navbar.links5 li
{
    width:20%;
}

jQuery

$(function()
{
    var n = $("ul.navbar").children().length-1;
    //Get the number of links: -1 because of logout
    $("ul.navbar").addClass("links"+n);
});

Alternatively, you could just directly modify the width with jQuery or PHP. Up to you. Either way, you should use percentages.

$(function()
{
    var n = $("ul.navbar").children().length-1;
    //Get the number of links: -1 because of logout
    $("ul.navbar").width((100/n)+"%");
});
Eric
Thanks for the suggestion. Probably, the items should be either <li>..</li> or <div>..</div>. Agree with your point that the navbar is not tabular data. Doesn't a list structure give a separate line for each item? I'm trying to get everything on the same line.
Martijn
I've reset the CSS of the `li` tags so that they `display:block` (like divs) and `float:left`. They should stack next to each other. The only reason I used `ul/li` tags is that they are more semantically correct. `div` tags would work too.
Eric