Pure CSS Horizontal Menu

Today I want to break down the steps of creating a pure CSS horizontal navigation menu. You see a lot of sites using them and while some are very creative, others are way off base as far as functionality is concerned. So without further ado, let’s begin to create a horizontal navigation menu.

Here is our blank document we will use and reference to throughout this tutorial:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Untitled Document</title>
    </head>

    <body>
    </body>
</html>

Let’s start off by creating a container for our navigation by using a div box. I will give my div box an id of “navigation”, but you can name it whatever you like as long as it corresponds to our CSS that we will write here in a second.

<body>
	<div id="navigation"></div>
</body>

Ok now that we have a simple container for our navigation links, we can begin to add some style rules.
Let’s start styling our navigation container by giving it a width, height and background color.

#navigation{
    width:100%;
    height:30px;
    background-color:#999;
}

If you are unfamiliar with writing CSS, I strongly suggest you read up on some CSS basic tutorials.

So let’s look at what we have done to our container.

fig1

Nothing special looking yet, but we now have our container setup to move forward in creating our navigation menu.
Now let’s add our menu items to our navigation container by using the unordered list method. Go back to our navigation container and add the following.

<body>
    <div id="navigation">
        <ul>
	    <li>Menu Item 1</li>
	    <li>Menu Item 2</li>
	    <li>Menu Item 3</li>
	    <li>Menu Item 4</li>
        </ul>
    </div>
</body>

Here is what our navigation menu should look like now.

fig2

You might be wondering how this is going to be a horizontal menu when our list items are ordered like a vertical menu. Well we still need to create a few more rules and styles to turn our menu into a horizontal look.

Go back up to our CSS and add the following rules:

#navigation{
    width:100%;
    height:30px;
    background-color:#999;
}

#navigation ul { }

#navigation ul li { }

(#navigation ul) points to any <ul> in our navigation container.
(#navigation ul li) points to <li> in our navigation container that is a child of <ul>.

Now that we are directly pointing to our <ul> and <li>, lets add some property’s to these guys.
Add these styles to your two new rules:

#navigation ul
{
    margin:0; 
    padding:0;
}

#navigation ul li
{
    display:inline; 
    height:30px; 
    float:left; 
    list-style:none;
}

What we have done here is we first told our <ul> to have a margin and padding to have a 0px.
We do this to remove any browser default margins and paddings that comes along with <ul> tags.

Next we point directly to our list-items and give them styles of display, height, float and list-style. The display and float styles are used align our list items in a horizontal fashion. We also set the height of each list item to 30px to match the height of our over all menu. Lastly is the list-style rule, we set it to none in-order to remove our browser default list-item bullets that come natively with the ordered/unordered lists.

fig3

Great! Now we are on track to creating a horizontal menu, but hmm it looks kind of bunched up. Its hard to tell where one menu item starts and another menu item ends.

To space out list items out, lets go back to our CSS rule for our <li> and add a left margin.

#navigation ul li
{
    display:inline; 
    height:30px; 
    float:left; 
    list-style:none; 
    margin-left:15px;
}

Here are our results.

fig4

Much better now, we can clearly see where each menu item starts and ends.

Let’s now turn our menu items into links by adding the following to your menu’s markup:

(We will not worry about where each item links to because this is out of the scope of this tutorial.)

<ul>
    <li><a href="#">Menu Item 1</a></li>
    <li><a href="#">Menu Item 2</a></li>
    <li><a href="#">Menu Item 3</a></li>
    <li><a href="#">Menu Item 4</a></li>
</ul>

Here is the results of each list items text being wrapped around the anchor tag (<a></a>):

fig5

YIKES, that’s just plain ugly looking right?

First, our menu items now have a solid blue color that is standard for all links. Second, each link now has an underline decoration. It’s very common for links to be styled with something more suitable for your sites theme, rather then use browser default styles.

So how do we fix these two issues? We first point to these links in our see by setting up two new rules like so:

#navigation li a { }

#navigation li a:hover { }

Our second rule is a hover rule. Hover rules (pseudo selector) allows us to dictate when the underline should appear below our links.

Here are our rules with their new styles:

#navigation li a
{
    color:#fff; 
    text-decoration:none;
}

#navigation li a:hover
{
    text-decoration:underline;
}

Now our links should have a white font color, but no underline if we are not hovering over them.
If we do hover over links though, then our links should receive a text decoration of underline.

Here are our results:

fig6

Our menu is looking great now, but you might be asking yourself. “Self, what if I want to have sub menu items? How would I go about creating something like that?”

Good question, let’s look at how we can create a sub menu’s for each menu item that is displayed only when a user hovers over our main menu items.

Let’s start to create our sub menu.

<ul>
      <li>sub menu item 1</li>
      <li>sub menu item 2</li>
      <li>sub menu item 3</li>
      <li>sub menu item 4</li>
</ul>

You now might be asking, “Where do we put this second unordered list of sub menu items?”. Well believe it or not we actually put it within each of our main menu items <li>.

Make your code look like the following.

<div id="navigation">
    <ul>
        <li>
        <a href="#">Menu Item 1</a>
            <ul> 
                <li>sub menu item 1</li> 
                <li>sub menu item 2</li> 
                <li>sub menu item 3</li> 
                <li>sub menu item 4</li> 
And, if not treated on time, sildenafil 100mg tab  these problems can leave severe side-effects. Such people should at least  50mg viagra sale take assistance from a chemical called 5-alpha reeducate. Precautions Whenever taking up with the medicine make it unfit for prolong use.Inability problem is hugely related with biochemistry of body. http://ronaldgreenwaldmd.com/procedures/back-procedures/thoracic-and-lumbar-tumor-removal/ sildenafil canada An example of a short term bout of impotence could happen if a man were cheating, he may not be able to perform because viagra prescription free  of associate guilt.             </ul>
        </li>

        <li>
        <a href="#">Menu Item 2</a>
            <ul> 
                <li>sub menu item 1</li> 
                <li>sub menu item 2</li> 
                <li>sub menu item 3</li> 
                <li>sub menu item 4</li> 
            </ul>
        </li>

        <li>
        <a href="#">Menu Item 3</a>
            <ul> 
                <li>sub menu item 1</li> 
                <li>sub menu item 2</li> 
                <li>sub menu item 3</li> 
                <li>sub menu item 4</li> 
            </ul>
        </li>

        <li>
        <a href="#">Menu Item 4</a>
            <ul> 
                <li>sub menu item 1</li> 
                <li>sub menu item 2</li> 
                <li>sub menu item 3</li> 
                <li>sub menu item 4</li> 
            </ul>
        </li>
    </ul>
</div>

Let’s look at the results of adding our sub menu items to our overall menu:

fig7

YIKES AGAIN! What happen to our menu, it’s all messed up now? We still have to create a few more CSS rules to get the look we are trying to accomplish.

Before we begin to write our new CSS rules lets think about how the whole thing is set up as far as parent to child elements are concerned.

#navigation -> ul -> li -> ul -> li

We have our navigation container, and its list of menu items. In each menu list item we start another list of menu items. So we need to create CSS rules that point specifically to our sub menu items.

Add the following to your CSS:

#navigation li ul { }

#navigation li:hover ul { }

#navigation li li { }

Here we are setting up rules that say, “if our navigation container list item has a sub unordered list and list items in it, then use these CSS rules”. We are also set up a hover rule so when a user hovers over a first level list item, it will hide or display its child sub menu.

Add these styles to our new rules:

#navigation li ul
{
    margin:0;
    padding:0;
    display:none;
}

#navigation li:hover ul
{
    display:block;
    width:160px;
}

#navigation li li
{
    list-style:none;
    display:list-item;
    width:100%;
}

We set our sub menu <ul> to have a display rule of none to hide our sub menu from the users.

Next we set a hover state to our main menu list items that says, “If a user hovers over any one of our main menu items, then indeed display it’s sub menu to the user”.

Finally we have to style our sub menu items to be listed in a vertical fashion, instead of following its parent’s rule of the horizontal look by setting them to be a display of list-item. Our sub menu items also need to have a width of 100%, this ensures that shorter combinations of link lengths under our fixed width of a sub menu, do not stack side by side, but rather always stack above and below each other.

Let’s see what our results look like now:

fig8

We in fact have our sub menu list items styled correctly, and our sub menu only displays when we hover its parent. The problem we now have, is that the sub menu is not being displayed directly under its hovered parent. We also have no background colors set for our sub menu, this makes it look a little weird and hard to read.

How do we fix these two issues? Well to position our sub menu correctly, we have to go back to our main menu list item’s rule we wrote a while back, and add a position property to it.

So make your main menu list item rule look like the following:

#navigation ul li
{
    display:inline;
    height:30px;
    float:left;
    list-style:none;
    margin-left:15px;
    position:relative;
}

This is preparing our submenu to be positioned absolute, but relative to our main menu items. So now add the a another position style, but this time to our sub menu:

#navigation li ul
{
    margin:0;
    padding:0;
    display:none;
    position:absolute;
}

When giving an element a position absolute, you are breaking the element out of the flow of design and searches for a stopping point in its parents. (hence giving the first level list items a position relative)

We not only have to add a position of absolute to our sub menus, but also a left and top in order to stop the browser from trying to guess where to place our sub menus.

All this left rule is saying is that we want our sub menu to be position left by 0px, and top by 20px to our relatively positioned parent list item:

#navigation li ul
{
    margin:0;
    padding:0;
    display:none;
    position:absolute;
    left:0; 
    top:20px;
}

We also wanted to fix our sub menu’s background color, so let’s add this and make it the same color as our main menu.

#navigation li ul
{
    margin:0;
    padding:0;
    display:none;
    position:absolute;
    left:0;
    top:20px;
    background-color:#999;
}

Let’s again take a look at our results.

fig9

Excellent, we have a great responding sub menu that pops up when you roll over our main menu items! But hey, how come our sub menu items have a font color of black, and they don’t have any text decoration? Well in short, we again need to wrap our sub menu items around anchor tags (<a></a>) and write our last CSS rules.

Make each sub menu’s markup look like the following:

<ul>
   <li><a href="#">sub menu item 1</a></li>
   <li><a href="#">sub menu item 2</a></li>
   <li><a href="#">sub menu item 3</a></li>
   <li><a href="#">sub menu item 4</a></li>
</ul>

And finally, add the following CSS rules and styles:

#navigation li li a
{
    color:#fff; 
    text-decoration:none;
}

#navigation li li a:hover
{
    text-decoration:underline;
}

Here we are pointing specifically to our sub menu links, and saying “If a link is not being hovered, then have no text decoration, if it is being hovered though, then add a text decoration of underline”.

Here are our final results:

fig10

View The Working Example:

And that’s it folks! You have now created a pure horizontal CSS menu that has a pop out sub menus.

This method of a horizontal menu is both cross-browser friendly and also the best method for a SEO approach.

Enjoy! Devin R. Olsen

Devin R. Olsen

Devin R. Olsen

Located in Portland Oregon. I like to teach, share and dabble deep into the digital dark arts of web and game development.

More Posts

Follow Me:TwitterFacebookGoogle Plus