Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS dynamic horizontal navigation menu to fill up specific width (table behavior)

I need to create a horizontal navigation menu with a changing number of items (this is important - I can't hard-code widths into the CSS and I don't want to calculate them with JS) that fill up to a certain width, let's say 800px.

With tables, enter image description here

<table width="800" cellspacing="0" cellpadding="0">
  <tr>
    <td>One</td>
    <td>Two</td>
    <td>Three</td>
    <td>Four</td>
    <td>Five Seven</td>
  </tr>
</table>

<style>
table td {
      padding: 5px 0;
      margin: 0;
      background: #fdd;
      border: 1px solid #f00;
      text-align: center;
    }
</style>

Note that longer items take up more space and I can add items into the HTML without changing anything in CSS and the menu items shrink to accommodate additional items - the whole menu never being shorter or longer than 800px.

As a menu isn't a semantically correct use of a table, can this be done with say a list and pure CSS?

like image 539
Zdeněk Gromnica Avatar asked Feb 22 '11 18:02

Zdeněk Gromnica


4 Answers

In browsers that support the table display CSS rules, yes:

<style>
  nav {display:table; width:800px; background:yellow}
  ul {display:table-row; }
  li {display:table-cell; border:1px solid red}
</style>

<nav>
 <ul>
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
  <li>Four</li>
  <li>Five Seven</li>
 </ul>
</nav>

Basically, you'd have to build a token table. In action: http://jsbin.com/urisa4

Otherwise: no, not if you can't compromise your requirements.

like image 184
DanMan Avatar answered Oct 08 '22 08:10

DanMan


You could do something like this:

<style type="text/css">
#container { width: 800px ; border: 1px dashed #333; }
#container div { width: inherit; display: table-cell; background: #ccc}
</style>

<div id="container">
    <div>Something</div>
    <div>Something</div>
    <div>Something</div>
</div>  

That way it fills up what you want, but can grow to a lot of items.

Hope this helps.

like image 23
TNC Avatar answered Oct 08 '22 09:10

TNC


The only way to do this with CSS is to hard-code the width of the li elements (assuming you'd be using the following structure):

  <ul>
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
    <li>Four</li>
    <li>Five Seven</li>
  </ul>

ul {
    width: 80%; /* or whatever */
}

ul li {
    width: 16%;
    padding: 1%;
}

JS Fiddle demo.

This leaves, potentially, an 'unused' 10% (to be used for margin or additional padding).

At some point in the future css calculations might be able to perform this more fluidly.

like image 45
David Thomas Avatar answered Oct 08 '22 08:10

David Thomas


This works, but i don´t think you want some think like this :)

<div class="master">
    <ul>
        <li>test1</li>
        <li>test2</li>
        <li>aölsdkfaösdlfk</li>
        <li>yeah baby</li>
        <li>hi</li>
    </ul>
</div>

.master {
   width:800px;
   background-color:black;
   height:100px;
   color:white;
    display:table;
}
table {
 width:100%;   
}

ul {
 display:table-row;  
 width:100%; 
}
li {
 display:table-cell;  
 width:auto; 
 margin:1px;
 border:1px solid white;
 background-color:red;
 text-align:center;
    vertical-align:middle;
}

http://jsfiddle.net/UnNyS/

like image 40
Luke Avatar answered Oct 08 '22 08:10

Luke