Currently Browsing: Home » How to easily create top navigation with CSS

How to easily create top navigation with CSS

Navigation is a vital part of all websites. Visitors must have ways to traverse through pages to find what they need. Top navigation is a specific style in which links are placed at the top of a website. In this tutorial, we will explore the creation of a pure CSS top navigation.

Note: This article is for CSS beginners!

Navigation

What makes top navigation so special?

When a user first visits a site, they immediately see the top half of a web page. For a quick fact, this half is known as the area above the fold.

Top navigation concentrates on the above property. By having navigation in the area a user first looks at, links gain more attention. This principle makes top navigation a viable alternative to the regular sidebar menu.

How is a top navigation menu created?

Top navigation menus are typically created through HTML and CSS, though JavaScript can help spice them up.

HTML

A navigation menu is inherently a type of list. Thus, it is only proper to contain this sort of menu in an HTML list:

<ul>
<li><a href="/">Home</li>
<li><a href="/about/">About</li>
<li><a href="/contact-us/">Contact Us</li>
<li><a href="/portfolio/">Portfolio</li>
<li><a href="/gallery/">Gallery</li>
<ul>

The above snippet contains an unordered list with links in each list item. It will be the base for our CSS.

CSS

Bullet Points

Now, when you first look at an unordered list, you will see something like this:

Unordered List

Notice how I’m using firebug and creating custom HTML + CSS within a blank page that has no URL. It is a key add-on to firefox that all web developers should have. With that side-note finished, let’s return to the problem:

There are little bullet points at the beginning of each element. In our case, these are unnecessary. We need a simple list with no bullet points that can be displayed horizontally. To remove this effect, we can use the list-style-type property:

ul {
list-style-type: none;
}

No Bullet Points

Horizontal Display

Next, we must remove the normal vertical-style display of the unordered list. This will take a small bit of work.

The first thing we must notice is that list items are normally displayed in a “block box.” This is specified with the CSS property display: list-item;. Unfortunately, this produces a line break before and after each list item. We must change this property to display the items in a one single line. This is simply done by changing the display property:

li {
display: inline;
}

The above CSS statement changes the display of the list elements so that they are next to one another in a horizontal line.

Along with this, it is also a good rule of thumb to float each list element to the left. This will remove browser inconsistencies and also place the list in the left most position because floated elements stack. Essentially, this means that the list elements will be placed side by side and not on top of one another:

li {
float: left;
}

Horizontal Menu

A word of caution

Let me side-track a bit to explain a problem that you may run into when customizing this menu. Once you complete writing the above code, you might want to add a left-offset to each list element in order to space them out:

li {
float: left;
display: inline;
margin-left: 20px;
}

Do you see anything wrong with this?

The old double-margin trick

An element that is floated left with a left margin. This should immediately put up a flag in your head. When a floated element is given a margin that is on the same side as the float, IE 6 doubles the margin. Just remember to take this into account if you want a left margin.

Now that we’ve avoided that calamity, let’s move forward.

Adding some inital style

Now, I feel that this menu looks very bland at this point. I want to spice it up a bit. Let’s add a custom font and some link styling:

body {
font: 14px/22px Georgia, "Times New Roman", Times, Serif;
}

a {
color: #DA4B4B;
text-decoration: none;
}

a:hover {
color: #000;
}

That might be a bit much to digest. Let me explain what is going on.

The first thing we do is set an overall font. It has a size of 14px, line-height of 22px, and font-family of Georgia, “Times New Roman”, Times, Serif. We then move on to our links and set a color for them. Notice how we also remove the default underlining through text-decoration: none. Finally, we set hover styles. The :hover selector is a psuedo-class that activates every time the mouse hovers over a link. When this does occur, we change the link color to black – #000.

Styled List

At this point, many of you must be annoyed with how closely each list element is placed next to one another. Let’s fix this up.

Styling the links

If you scroll to the top of the CSS blog, you will notice that a large portion of each navigation element can be hovered over to click on it. In other words, you don’t have to click directly on “What’s new?”. Instead, you can place your cursor a bit under it and still click to have the same effect.

How can we accomplish this?

It is actually quite simple to create this effect. The key is in each link. Instead of displaying the links normally, we can put them in a block box. When this occurs, the whole area the text takes up will also be a part of the link. Well, you might ask, isn’t this what links normally do?

Here is where the tricky part comes in. Links do take up the text area, but they do not consider line-height. If a link is displayed as block, line-height will determine the actual height unless overridden. This can work to our advantage! We can simply set the line-height of the unordered list to achieve a larger link:

ul {
line-height: 50px;
}

li a {
display: block;
border: 1px solid #000;
}

Notice how I am setting a border around the link so you can see the dimensions of it.

Block Link

We are almost there! At this point, we can finally get rid of that bad spacing. All we need to do is add padding and/or margin to the link element. In this case, I will add a 20px left and right padding:

li a {
padding: 0 20px;
}

Link With Padding

Finally, we can put in a few extra styles to make it look nice:

li a {
background: #ececec;
font-size: 18px;
border: 1px solid #ccc;
}

li a:hover {
background: #f6f6f6;
font-size: 20px;
}

In this above snippet, we just add a background color, border, and font size to each link element. These values then get adjusted when the mouse hovers over them.

Here is the final product:

Final Product

The Finished CSS

body {
font: 14px/22px Georgia, "Times New Roman", Times, Serif;
}

a {
color: #DA4B4B;
text-decoration: none;
}

a:hover {
color: #000;
}

ul {
list-style-type: none;
line-height: 50px;
}

li {
display: inline;
float: left;
}

li a {
display: block;
background: #ececec;
padding: 0 20px;
font-size: 18px;
border: 1px solid #ccc;
}

li a:hover {
background: #f2f2f2;
font-size: 20px;
}

Conclusion

I hope this helped refine your CSS skills! Stay tuned for more and feel free to drop a comment with any questions/comments/concerns!

Tags:

This entry was posted on Wednesday, November 11th, 2009 at 10:46:13. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

4 Responses to “How to easily create top navigation with CSS”

  1. Eric Newton says:

    Thanks for the walkthrough… this helped me understand the css behind unordered lists…

    Any chance about talking about browser inconsistencies?

    Is there a way to affect the LI border? Like when you hover over one, have the border go to 3px and background-color to silver to mimic a depressed-in look?

  2. @Eric: Yes, that’s completely possible. Consider this:

    li a:hover {
         border-width: 3px;
         background: /* put your silver hex color here */;
    }

    As for browser inconsistencies, I believe this works fine in IE6, IE7, IE8, FireFox, Safari, and Google Chrome, although I have not explicitly looked for tiny details (as long as it looks about the same, there is no need to make changes).

  3. Castle says:

    Hi.. Good article.

    One question. How to add support to subpages? For example 4 levels?

    Thanks,
    Daniel

Leave a Reply

Want to be notified when someone replies? Subscribe to this post's comment RSS feed.
Any field marked with a * is required.