Fluid navigation items of different widths with equidistant spacing

Hi there,

Ok, this has me really stumped.

I’d like to create a fluid horizontal navigation list of links, where the nav links are evenly spaced and take up the full width of the enclosing container. The Nav links are all different widths. The first link should be left-aligned and the last link should be right aligned. Something like this: http://img547.imageshack.us/img547/9901/screenxa.png. The problem I’m having is when the browser is resized keeping the elements equally spaced.

I’ve experimented with using table layout for the ul:

ul {display: table;width: 100%;}
li {display: table-cell;}
a {display: block;} 

giving each of the elements a percentage (working out the width of the text, dividing that by the max width of the page and then times by 100 for the percentage). I thought this would work but as the browser is resized the spacing is not maintained. Problem here is that I work out all the widths of the text and convert to percentages. All seven percentages added up come to 57.2%. I’ve then divided the remaining 42.8% by the seven list items and add that on to the percentage for each element. I think this is where I’m going wrong perhaps - I don’t think dividing the remainder by 7 and then adding that on to each of the items is the correct thing to do

header nav ul {width: 100%;overflow: hidden; height: 20px;position: relative}
header nav ul li {text-align:left;float:left;width: 14%}
header nav ul li.home {width: 10.3%}
header nav ul li.about {width: 11.4%}
header nav ul li.collections {width: 16.3%}
header nav ul li.stockists {width: 14.3%}
header nav ul li.trade-enquiries {width:18.6% }
header nav ul li.press {width: 10.8%}
header nav ul li.contact {width: 15.7%}

also using inline-block on the li elements as suggested by this article:

but nothing seems to keep the elements evenly spaced at all browser sizes.

Is there any way this can be achieved using CSS? I’m having quite a hard time finding a solution that works!

This won’t help you now, but flex box is the ideal solution. Unfortunately there is not wide enough [URL=“http://caniuse.com/#search=flex”]browser support.

Hi,

I would just use display:table-cell without any widths and let the cells space themselves out. It will be close enough not to worry about.

e.g.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style type="text/css">
ul.nav2 {
	list-style:none;
	background:#000;
	color:#fff;
	margin:0 auto;
	width:80%;
	display:table;
}
.nav2 li {
	display:table-cell;
	padding:5px;
	text-align:center
}
.nav2 a {
	display:block;
	color:#fff;
	text-decoration:none;
	text-transform:uppercase;
}

/* second example below */
</style>
</head>

<body>
<ul class="nav2">
		<li><a href="#">Home</a></li>
		<li><a href="#">Collections</a></li>
		<li><a href="#">About&nbsp;Us</a></li>
		<li><a href="#">Stockists</a></li>
		<li><a href="#">Trade&nbsp;Enquiries</a></li>
		<li><a href="#">Press</a></li>
		<li><a href="#">Contact&nbsp;Us</a></li>
</ul>
</body>
</html>

There is a trick you can use using text-align justify to space elements equally but it needs some setting up.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Distributed Horizontal Menu</title>
<meta name="generator" content="PSPad editor, www.pspad.com">
<style type="text/css">
.nav {
	margin:auto;
	list-style:none;
	padding:0 10px;
	min-width:40em;
	width:80%;
	overflow:hidden;
	text-align:justify;
	background:#000;
	color:#fff;
	font-size:80%;
	line-height:3em;
	height:3em;
}
.nav li { display:inline; }
.nav li.last { margin-right:100%; }
.nav li a {
	display:inline-block;
	line-height:3em;
	vertical-align:middle;
	text-decoration:none;
	text-transform:uppercase;
	color:#fff;
}
</style>
</head>
<body>
<ul class="nav">
		<li><a href="#">Home</a></li>
		<li><a href="#">Collections</a></li>
		<li><a href="#">About&nbsp;Us</a></li>
		<li><a href="#">Stockists</a></li>
		<li><a href="#">Trade&nbsp;Enquiries</a></li>
		<li><a href="#">Press</a></li>
		<li class="last"><a href="#">Contact&nbsp;Us</a> &nbsp;</li>
		<!-- the last non breaking space is needed for the justify effect -->
</ul>
</body>
</html>

This may be considered a “groaner” because it uses empty tags as spacers, but it’s easy and the performance is flawless in IE8+ (as far as I know :slight_smile: ).


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<!--
http://www.sitepoint.com/forums/showthread.php?1063675-Fluid-navigation-items-of-different-widths-with-equidistant-spacing
Thread: Fluid navigation items of different widths with equidistant spacing
2013.05.12 06:14
elduderino
-->
<head>
    <title>edge-to-edge menu</title>
    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
    <meta http-equiv="content-language" content="en-us">
    <style type="text/css">

div {
    background-color:#000;
    padding:4px 8px;
}
ul {
    display:table;
    width:100%;
    border-top:3px solid orange;
    padding-left:0;
    margin:0;
}
li {display:table-cell;}
.spacer {width:15%;}    /* the sum of all spacers cannot exceed 100% */
a {
    display:block;
    color:#fff;
    font-size:.8em;
    text-transform:uppercase;
    text-decoration:none;
    white-space:nowrap;
    padding:3px;
}
    </style>
</head>
<body>
<div>
    <ul>
        <li><a href="#">home</a></li>
        <li class="spacer"></li>
        <li><a href="#">collections</a></li>
        <li class="spacer"></li>
        <li><a href="#">about us</a></li>
        <li class="spacer"></li>
        <li><a href="#">stock lists</a></li>
        <li class="spacer"></li>
        <li><a href="#">trade enquiries</a></li>
        <li class="spacer"></li>
        <li><a href="#">press</a></li>
        <li class="spacer"></li>
        <li><a href="#">contact us</a></li>
    </ul>
</div>
</body>
</html>

Try out Text align: Justify like Paul suggested. I used that trick and it worked perfectly for me. You might want to visit Chris Coyier’s page on equidistant CSS objects for more information on it.

Heres the link: http://css-tricks.com/equidistant-objects-with-css/

Thanks :slight_smile: That was actually taken from a very old CSS quiz that we did and if done properly will work back to IE6.

For ie8+ you can drop the last   and use :after instead.

e.g.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Distributed Horizontal Menu</title>
<meta name="generator" content="PSPad editor, www.pspad.com">
<style type="text/css">
.nav {
	margin:auto;
	list-style:none;
	padding:0 10px;
	min-width:40em;
	width:80%;
	overflow:hidden;
	text-align:justify;
	background:#000;
	color:#fff;
	font-size:80%;
	line-height:3em;
	height:3em;
}
.nav li { display:inline; }
.nav li.last { margin-right:100%; }
.nav li a {
	display:inline-block;
	line-height:3em;
	vertical-align:middle;
	text-decoration:none;
	text-transform:uppercase;
	color:#fff;
}
.nav li.last:after{content:"\\00a0"}
</style>
</head>
<body>
<ul class="nav">
		<li><a href="#">Home</a></li>
		<li><a href="#">Collections</a></li>
		<li><a href="#">About&nbsp;Us</a></li>
		<li><a href="#">Stockists</a></li>
		<li><a href="#">Trade&nbsp;Enquiries</a></li>
		<li><a href="#">Press</a></li>
		<li class="last"><a href="#">Contact&nbsp;Us</a></li>
</ul>
</body>
</html>


Awesome! Thanks for the justified code guys :slight_smile: - works a treat!