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,
<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?
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.
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.
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.
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/