Navigation Bars

From CSS Standards FAQ

Jump to: navigation, search



Navigation bars are (markupwise) a list of links, thus a <ul> element is a perfect choice to mark those up with.

<ul id="navbar">
    <li id="nav_Home"><a href="home.html">Home</a></li>
    <li id="nav_Music"><a href="music.html" title="Free Music Collection">Music</a></li>
    <li id="nav_Logout"><a href="">Logout</a></li>

This will work for both, horizontal and vertical, navigation bars as well as for dropdowns.


First of all, with most navigation bars you wouldn't want to have the bullets <ul> element gives us. We are going to use list-style-type property to remove them.

Another aspect that we need to account for is the default margin/padding set on the <ul> element and <li> element.

#navbar li {
    list-style-type: none;
    margin: 0;
    padding: 0;

Making Things Pretty

Often you'd want to use images as "buttons" for your navigation bars. I am going to use a text-indent method to implement an image replacement technique for the sake of simplicity of my example, however, feel free to use any one you favor most.

Note: Personally I often prefer the Gilder/Levin Image Replacement Method since it accomodates for images off/still loading/failed to download scenarios

Since we already have id="" attributes on our <li> elements, we are going to use those to specify which image is loaded for every link.

Let's assume that all of our "buttons" are of the same size.

By default <a> element is inline-level element. Width and height properties do NOT applie to inline-level element, but since we need them we are going to use display property on our <a> elements

#nav_Home   a,
#nav_Music  a,
#nav_Logout a {
    display:     block;
    width:       100px;
    height:      40px;
    text-indent: -9999px;
    overflow:    hidden; /* fix "dotted border" sticking out during click */

#nav_Home   a { background: url(home_button.png);   }
#nav_Music  a { background: url(music_button.png);  }
#nav_Logout a { background: url(logout_button.png); }

Viola! Our vertical navigation bar is ready for action.

Going Horizontal

There two most common methods to make horizontal navigation bars. First of all <li> elements are block-level, thus they will stack one under another, not horizontally. Second of all, since we are using a { display: block; } to make buttons with images (if you followed this tutorial from the top) those will stack as well.

Floats to the resque

If the property float doesn't ring a bell to you I would suggest you read up the specs and Foatutorial, it is not the only time you are going to use this property.

All we need to do is float our <li> elements... in a perfect world. However, IE < 7 with it's expanding box model bugs won't like this a lot and will need some extra sugar, luckly it's not much, all we need to do is float the <a> elements.

#navbar {
    overflow: hidden;
    display: inline-block;
#navbar { display: block; }

#navbar li,
#navbar a { float: left; }

The overflow: hidden and display toggle is there to contain floats, pick any method you want to use except for clearing element method, this is not a place for it. Dispay toggling is there to give IE "layout" since that's what it needs to contain floats.

Note: if you don't contain floats, you are likely to have some margin issues with elements following your navigation bar

Note 2: you don't actually have to set width, height or display: block on your <a> elements. Without width you'll get a shrink-wrap effect, thus your buttons will be as wide as needed and float will make <a> elements behave as block-level elements.

Well, now our nav is horizontal... However...

Caveats With Floated Navs

  • You can't center them. If you need shrink-wrap effect consider using display: inline method (see below) or read Centering Tutorial to find out how to shrink-wrap and center at the same time.
  • The "buttons" will drop on the next line if you resize the browser, to fix that set some fixed width on the container (the <ul> element): #navbar { width: 300px; }

Display Method

Other, simplier method is to use display property on our <li> elements with value set to inline.

#navbar li { display: inline; }

However, note:

Caveats with Display Method

  • You won't be able to set width or height on your "buttons"
  • You should remove a { display: block; }
  • Centering your nav would be done using text-align property on the container: #navbar { text-align: center; }
  • You'll need to remove white space between <li> elements in the source code (yes, new lines are white-space too). To maintain readability, one may choose to write the code out like this:
<ul id="navbar"
    ><li id="nav_Home"><a href="home.html">Home</a></li
    ><li id="nav_Music"><a href="music.html" title="Free Music Collection">Music</a></li
    ><li id="nav_Logout"><a href="">Logout</a></li

<!-- note the position of closing and opening angle brackets...
      no white space in between <li> elements -->

Further Reading

Personal tools