Create An Elegant CSS3 Navigation Menu

by in Tutorials on 11th Jul 2012 · Comments

Navigation menus are the most important portion of any website. A website's navigation menu should be usable, attractive and intuitive. In this tutorial we will be creating simple and professional looking menu with both horizontal and vertical orientation.

Along the way, we will explore the usage of CSS3 features like gradients, box-shodows and text-shadows. Since we won't be using any images to style this menu, it is extremely easy to customize to suit your needs. The image below shows a preview of the navigation menu that we will be building. Follow this link to check out the working demo.

Create An Elegant CSS3 Navigation Menu


Let's Get Started

Before getting started with this tutorial, I would like to mention that since CSS3 is not completely supported across all browsers, features like CSS3 - gradients might not work in older browsers. With that in mind, let's get started!

Step 1. Basic HTML Markup

The HTML markup that we will be using is very simple, after the HTML5 Doctype declaration, we have the head and title tags. After the body tag, we have a div tag with a class of wrap to give the content area a width of 960px and to center-align the content.

For the navigation menu, we will start with the HTML5 tag since this tag is used to provide additional semantic meaning to a section of navigation links. Inside this tag we will have a regular unordered list of links. It is to be noted that I have created two sets of navigation links, one with an id of top-nav and the other with an id of vertical. Here's the entire HTML markup, followed by a preview of what we have created so far.

Unstyled

Step 2. Adding Basic Styles

Create a new CSS file called master.css and add a link to this file in your main HTML file. We will start our CSS file with a quick reset to obtain uniformity across different browsers. Let's also add a subtle background image to our page. We can add the background image with the help of the following declaration.

/* --------Base Styles--------- */
body, html  {
    margin: 0;
    padding: 0;
}

body  {
    background: #404044 url("images/bg.png") left top;
    font: 14px/1.5 Verdana, Helvetica, Arial, sans-serif;
}

div.wrap  {
    width: 960px;
    margin: 50px auto;
}

Step 3. Horizontal Navigation Menu

Now that we have the basic layout up and running, lets get started with designing the navigation menu. Here's the css code for styling the ul tag.

/* -------- Horizontal Menu --------- */
ul#top_nav  {
    border: 1px solid #292929;
    margin: 0;
    padding: 0;
    width: 850px;
    margin-bottom: 50px;

    -webkit-box-shadow: 0 3px 3px #3c3c40;
    -moz-box-shadow: 0 3px 3px #3c3c40;
    box-shadow: 0 3px 3px #3c3c40;
}

ul#top_nav li {
    list-style: none;
    float: left;
}

We will start by giving the unordered list tag ul a width of 850px and a 1 pixel thick border of color #292929. We will also remove the padding and margins associated with the unordered list. The key thing to note in the style declaration for the ul#topnav is the box-shadow declaration. Here, -moz- and -webkit- browser prefixes have been used to ensure that this works in gecko and webkit based browsers. The syntax for adding the box-shadow might look complicated, but let us break it down into smaller chunks to understand it better.

* --------Box Shadow--------- */
-webkit-box-shadow: 0 3px 3px #3c3c40;
-moz-box-shadow: 0 3px 3px #3c3c40;
box-shadow: 0 3px 3px #3c3c40;

Here, the first zero indicates the x-offset and the 3px indicates that we have provided a 3-pixel offset in the y-direction. The next value of 3px indicates the blur. This is followed by the color declaration of #3c3c40.

Also note that we have floated the list-items in order to align them in a straight line. We have also removed the default list-style-type by providing it a value of none. Now let's add the CSS code for styling the links.

ul#top_nav li a {
    display: block;
    text-align: center;
    height: 50px;
    width: 140px;
    line-height: 50px;
    color: #fff;
		  
    text-decoration: none;
    text-shadow: 0 1px 0 #000;
	
    border-right: 1px solid #323235;
    border-left: 1px solid rgba(255, 255, 255, 0.2);
		  
    background-image: -moz-linear-gradient(top, #535357, #3c3c3f);
    background-image: -ms-linear-gradient(top, #535357, #3c3c3f);
    background-image: -webkit-linear-gradient(top, #535357, #3c3c3f);
    background-image: linear-gradient(top, #535357, #3c3c3f);
		  
    -webkit-box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2), 0 1px 0px #292929;
    -moz-box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2), 0 1px 0px #292929;
    box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2), 0 1px 0px #292929;
}

The first thing to note here is that we have changed the default display style for the anchor tag by making it a block-level element. Next, we have given it a width of 140px and a height of 50px. Also, we have removed the underline from the links by setting the text-decoration to none. The key things to note in the above code snippet are the declaration for adding the gradient and the shadow.

Lets focus on adding the gradient first. If we analyze the gradient piece-by-piece, we'll find that this code snippet is not as daunting as it looks. Here we are adding a linear gradient that goes from colors #535357 to #3c3c3f. Similar to the earlier declaration for the box-shadow, the moz, -webkit-, -ms prefixes have been added to ensure that this works seamlessly across all modern browsers.

background-image: -moz-linear-gradient(top, #535357, #3c3c3f);
background-image: -ms-linear-gradient(top, #535357, #3c3c3f);
background-image: -webkit-linear-gradient(top, #535357, #3c3c3f);
background-image: linear-gradient(top, #535357, #3c3c3f);

Now, our horizontal navigation bar is almost complete. We are only left with adding the hover and active states for the links. Lets take a look at the code first.

ul#top_nav li a:hover {
    text-shadow: 0 0 8px rgba(255, 255, 255, 0.2);
    background-image: -moz-linear-gradient(top, #565658, #313132);
    background-image: -ms-linear-gradient(top, #565658, #313132);
    background-image: -webkit-linear-gradient(top, #565658, #313132);
    background-image: linear-gradient(top, #565658, #313132);
		  
    -webkit-box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2), 0 1px 0px #292929;
    -moz-box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2), 0 1px 0px #292929;
    box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2), 0 1px 0px #292929;
}

ul#top_nav li a:active  {
    background: #414142;
    -webkit-box-shadow: inset 0 2px 3px rgba(0,0,0, 0.2);
    -moz-box-shadow: inset 0 2px 3px rgba(0,0,0, 0.2);
    box-shadow: inset 0 2px 3px rgba(0,0,0, 0.2);
}

For the hover state for the link, i.e. when the cursor is over the link, we will be changing the gradient to go from #565658 to #313132. Also, we will be adding a subtle box-shadow with the keyword inset to add a inner-shadow effect to the link. The key point to note here is that we can add multiple shadows to an element by separating it with commas.

For the active state for the link, i.e. when the mouse is being pressed on the link, we have removed the background gradient and replaced it with a solid color #414142. Also, we have added a dark box-shadow with the inset keyword, to add a pressed-in effect to the link.

Step 3. Vertical Navigation Menu

The vertical navigation menu is almost exactly similar to the horizontal navigation bar that we have created so far. The only change in CSS code for this menu is that we won't be floating the list-items li, but will provide it a width of 300px and a height of 50px. Here's the entire CSS code for the vertical navigation menu.

/* ---------- Vertical --------*/
ul#vertical {
    margin: 0;
    padding: 0;
    width: 300px;
    border: 1px solid #292929;

    -webkit-box-shadow: 0 0 5px #3c3c40;
    -moz-box-shadow: 0 0 5px #3c3c40;
    box-shadow: 0 0 5px #3c3c40;		  
}

ul#vertical li  {
    list-style-type: none;
		  
    background-image: -moz-linear-gradient(top, #535357, #3c3c3f);
    background-image: -ms-linear-gradient(top, #535357, #3c3c3f);
    background-image: -webkit-linear-gradient(top, #535357, #3c3c3f);
    background-image: linear-gradient(top, #535357, #3c3c3f);
}

ul#vertical li a  {
    border-bottom: 1px solid #292929;
    display: block;
    padding: 15px 30px;
    color: #fff;
    text-decoration: none;
    text-shadow: 0 1px 0 #000;
    -webkit-box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2);
    -moz-box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2);
    box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2);
}

ul#vertical li a:hover {
    text-shadow: 0 0 8px rgba(255, 255, 255, 0.2);
    background-color: #59595c;
		  
    -webkit-box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2), 0 1px 0px #292929;
    -moz-box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2), 0 1px 0px #292929;
    box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2), 0 1px 0px #292929;
}

ul#vertical li a:active {
    background-color: #414142;
    -webkit-box-shadow: inset 0 2px 3px rgba(0,0,0, 0.2);
    -moz-box-shadow: inset 0 2px 3px rgba(0,0,0, 0.2);
    box-shadow: inset 0 2px 3px rgba(0,0,0, 0.2);
}

Conclusion

Our navigation menu is now complete. Check out the demo to see how the completed menu looks. If you are lost at any point or couldn't follow the tutorial, no worries, we've got the tutorial zipped in a single file that you can download to your desktop. Hope you enjoyed this tutorial. Feel free to experiment with these features and don't forget to share your thoughts.

Bharani M is a designer/developer from New Delhi, India. He is currently working on his first web app, Resumonk - an online resume builder that helps others create a professional and beautiful resume in minutes.