I'd like to stretch 6 nav items evenly across a 900px container, with an even amount of white space between. For instance...
---| 900px Container |---
---| HOME ABOUT BASIC SERVICES SPECIALTY SERVICES OUR STAFF CONTACT US |---
Currently, the best method I can find to do this is the following:
nav ul {
width: 900px;
margin: 0 auto;
}
nav li {
line-height: 87px;
float: left;
text-align: center;
width: 150px;
}
The PROBLEM with this is two fold. First of all, it doesn't truly justify it, but rather spreads the li tags evenly throughout the ul tag.. creating uneven white-space between smaller menu items like "HOME" or "ABOUT" and larger ones like "BASIC SERVICES".
The second problem is that the layout breaks if a nav item is larger than 150px, which SPECIALTY SERVICES is - even though there is more than enough space for the whole nav.
Can anyone solve this for me? I've been scouring the web for solutions, and they all seem to come up short. CSS / HTML only if possible...
Thanks!
UPDATE (7/29/13): Using table-cell is the best modern way to implement this layout. See felix's answer below. The table cell
property works on 94% of browsers currently. You'll have to do something about IE7 and below, but otherwise should be ok.
UPDATE (7/30/13): Unfortunately, there is a webkit bug that impacts this if you're combining this layout with Media Queries. For now you'll have to avoid changing the 'display' property. See Webkit Bug.
UPDATE (7/25/14): There is a better solution to this below now involving text-align: justify. Using this is simpler and you'll avoid the Webkit bug.
Use text-align:justify
on the container, this way it will work no matter how many elements you have in your list (you don't have to work out % widths for each list item
<ul id="nav">
<li><a href="#">HOME</a></li>
<li><a href="#">ABOUT</a></li>
<li><a href="#">BASIC SERVICES</a></li>
<li><a href="#">OUR STAFF</a></li>
<li><a href="#">CONTACT US</a></li>
</ul>
CSS
#nav {
text-align: justify;
min-width: 500px;
}
#nav:after {
content: '';
display: inline-block;
width: 100%;
}
#nav li {
display: inline-block;
}
This one really works. Also has the benefit that you can use media queries to easily turn off the horizontal style — for instance if you want to stack them vertically when on mobile phone.
HTML
<ul id="nav">
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
</ul>
CSS
#nav {
display: table;
height: 87px;
width: 100%;
}
#nav li {
display: table-cell;
height: 87px;
width: 16.666666667%; /* (100 / numItems)% */
line-height: 87px;
text-align: center;
background: #ddd;
border-right: 1px solid #fff;
white-space: nowrap;
}
@media (max-width: 767px) {
#nav li {
display: block;
width: 100%;
}
}
if you can, use flexbox:
<ul>
<li>HOME</li>
<li>ABOUT US</li>
<li>SERVICES</li>
<li>PREVIOUS PROJECTS</li>
<li>TESTIMONIALS</li>
<li>NEWS</li>
<li>RESEARCH & DEV</li>
<li>CONTACT</li>
</ul>
ul {
display: flex;
justify-content:space-between;
list-style-type: none;
}
jsfiddle: http://jsfiddle.net/RAaJ8/
Browser support is actually quite good (with prefixes an other nasty stuff): http://caniuse.com/flexbox
An ideal solution will:
- Automatically scale to the width of the navigation container
- Support a dynamic number of menu items.
Using a simple ul
menu inside of an nav
container, we can build a solution that meets the above requirements.
HTML
<nav>
<ul>
<li>Home</li>
<li>About</li>
<li>Basic Services</li>
<li>Specialty Services</li>
<li>Our Staff</li>
<li>Contact Us</li>
</ul>
</nav>
First, we need to force the ul
to have the full width of its nav
container. To accomplish this, we will use the :after
psuedo-element with width: 100%
.
This achieves our goal perfectly, but adds trailing whitespace from the psuedo-element. We can remove this whitespace across all browsers through IE8 by setting the line-height
of the ul
to 0 and setting it back to 100% on its li
children. See the example CodePen and solution below:
CSS
nav {
width: 900px;
}
nav ul {
text-align: justify;
line-height: 0;
margin: 0;
padding: 0;
}
nav ul:after {
content: '';
display: inline-block;
width: 100%;
}
nav ul li {
display: inline-block;
line-height: 100%;
}
I tried all the above and found them wanting. This is the simplest most flexible solution I could figure out (thanks to all of the above for inspiration).
HTML
<div id="container">
<ul>
<li>HOME</li>
<li>ABOUT US</li>
<li>SERVICES</li>
<li>PREVIOUS PROJECTS</li>
<li>TESTIMONIALS</li>
<li>NEWS</li>
<li>RESEARCH & DEV</li>
<li>CONTACT</li>
</ul>
</div>
CSS
div#container{
width:900px;
background-color:#eee;
padding:20px;
}
ul {
display:table;
width: 100%;
margin:0 0;
-webkit-padding-start:0px; /* reset chrome default */
}
ul li {
display:table-cell;
height:30px;
line-height:30px;
font-size:12px;
padding:20px 10px;
text-align: center;
background-color:#999;
border-right:2px solid #fff;
}
ul li:first-child {
border-radius:10px 0 0 10px;
}
ul li:last-child {
border-radius:0 10px 10px 0;
border-right:0 none;
}
You can drop the first/last child-rounded ends, obviously, but I think they're real purdy (and so does your client ;)
The container width limits the horizontal list, but you can ditch this and just apply an absolute value to the UL if you like.
Fiddle with it, if you like..
This should do it for you.
<div id="nav-wrap">
<ul id="nav">
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
</ul>
</div>
#nav-wrap {
float: left;
height: 87px;
width: 900px;
}
#nav {
display: inline;
height: 87px;
width: 100%;
}
.nav-item {
float: left;
height: 87px;
line-height: 87px;
text-align: center;
text-decoration: none;
width: 150px;
}
Have you tried setting the li width to, say, 16% with a margin of 0.5%?
nav li {
line-height: 87px;
float: left;
text-align: center;
width: 16%;
margin-right: 0.5%;
}
edit: I would set the UL to 100% width:
nav ul { width: 100%; margin: 0 auto; }
This is the sort of thing that the CSS flexbox model will fix, because it will let you specify that each li will receive an equal proportion of the remaining width.
I tried so many different things and finally found what worked best for me was simply adding in
padding-right: 28px;
I played around with the padding to get the right amount to evenly space the items.
Instead of defining the width, you could just put a margin-left on your li, so that the spacing is consistent, and just make sure the margin(s)+li fit within 900px.
nav li {
line-height: 87px;
float: left;
text-align: center;
margin-left: 35px;
}
Hope this helps.
<!DOCTYPE html>
<html lang="en">
<head>
<style>
#container { width: 100%; border: 1px solid black; display: block; text-align: justify; }
object, span { display: inline-block; }
span { width: 100%; }
</style>
</head>
<div id="container">
<object>
<div>
alpha
</div>
</object>
<object>
<div>
beta
</div>
</object>
<object>
<div>
charlie
</div>
</object>
<object>
<div>
delta
</div>
</object>
<object>
<div>
epsilon
</div>
</object>
<object>
<div>
foxtrot
</div>
</object>
<span></span>
</div>
</html>
I'm hesitant to offer this as it misuses ye olde html. It's not a GOOD solution but it is a solution: use a table.
CSS:
table.navigation {
width: 990px;
}
table.navigation td {
text-align: center;
}
HTML:
<table cellpadding="0" cellspacing="0" border="0" class="navigation">
<tr>
<td>HOME</td>
<td>ABOUT</td>
<td>BASIC SERVICES</td>
<td>SPECIALTY SERVICES</td>
<td>OUR STAFF</td>
<td>CONTACT US</td>
</tr>
</table>
This is not what tables were created to do but until we can reliably perform the same action in a better way I guess it is just about permissable.
来源:https://stackoverflow.com/questions/5060923/how-to-stretch-a-fixed-number-of-horizontal-navigation-items-evenly-and-fully-ac