Creating menus: Horizontal navigation > Explained

Written by: Emanuel Blagonic

Published on: September 27, 2006

Few days ago I was writing about creating vertical navigation using unordered lists and CSS. Now it is time to show you how to create horizontal navigation with the same things. The beauty of CSS is that we don’t need to change anything in the XHTML code of our previous navigation. Although there are no limitations in creating horizontal navigation, in this article I will show you how to create clean and simple horizontal navigation, but without sub-navigation. I will cover sub-navigation in some other article on this topic.

How to start?

We will just copy and paste the code we used in creating vertical navigation, with only exception that we will not have the sub-navigation. So, nested lists — bye, bye. Here is our sample code.

<div id="navigation">
	<li><a href="#" title="Homepage" class="selected">Homepage</a></li>
	<li><a href="#" title="About us">About us</a></li>
	<li><a href="#" title="Projects">Projects</a></li>
	<li><a href="#" title="Contact">Contact</a></li>

The CSS for this example hasn’t changed much from our last navigation example. Here is our new CSS.

#navigation {
#navigation ul {
#navigation li { display:inline; }
#navigation a {
	padding:5px 10px;
#navigation a:hover, #navigation a.selected {
#navigation a.selected {

What are the changes?

We obviously removed the width of navigation from #navigation { width:200px } because we do not want our navigation to expand into the next row when 200px are reached. This way, the navigation will expand to the end of #container (which is in our case 500px, what is enough).

We also added a new line #navigation li { display:inline; } which says that our navigation elements will display in one line.

Now comes the tricky part which actually displays the navigation element. From #navigation a { ... } we removed display:block; and border-bottom:1px solid #fff;. First because we do not want our navigation elements to be displayed as block (we will come to this part a little later), and second because we no longer need the spacer for removing the elements. We are displaying the “buttons” with padding: 5px 10px;. That’s all you need if you want your navigation to display properly in Firefox, but what’s with IE? To prevent any problems with our beloved Internet Explorer we will add the next line #navigation a { display:inline-block; }.

What happens if you want elements of exact height?

We have our horizontal navigation, that works just fine. But what happens if we want our navigation elements to be of exact height. Problems. Here is the solution. We wanted our elements to be displayed with 50px height.

First, you can calculate manually the size of the elements like this (1.1em (11px) + padding-top:19px; + padding-bottom:20px;). This is OK, but when you want to enlarge text size, the button expands with height.

Second, and my preferred option is to calculate the height using line-height. We will use line-hegiht:4.5em; to get the same effect. But when your user wants to enlarge the text size, the button stays intact in both Firefox and IE. Why to define line-height in ems instead of pixels, you ask. If you define the line-height in pixels Firefox will not enlarge the background of a button a single bit. Using ems instead, will make no harm to Firefox nor to IE.

There is also one difference between these two modes of displaying horizontal navigation. While in the first case, there is no need to display our buttons as blocks, to display the second navigation elements as wanted, we will use display:block; and float:left;. This is here because with no top and bottom padding, the buttons will not display height that exceeds the height of the text. The width will display normally because we defined left and right padding.

Please note: if you want to remove the buttons one from another, you could use margin-right:5px;. This will work for both cases.

The example

Horizontal navigation example