A Different Top Navigation
When designing a new site, web designers usually face the age-old question: vertical or horizontal navigation? There are pros and cons to both solutions. One example being horizontal navigation limits the number of links you can have due to a limited page width. This is usually solved by including a drop down system. However, if you are attempting to make your particular site stand out, you might consider thinking outside the "norm".
In this tutorial, we will be doing precisely that. We will use jQuery to create a different multi-layered horizontal navigation system that is still intuitive enough for anyone to use for the first time.
To Learn:
At the end of this tutorial, we want to learn the following:
- How to create cross-browser rounded pure CSS corners
- Use jQuery to animate a top slider
- Use jQuery to control the appearance of children unordered lists when the parent list item is hovered over.
- Use jQuery to create a dynamic close capability
Objective:
At the end of this tutorial, we want to create a horizontal navigation system that does not use the typical drop down system.
Desired Effect
Functionality
Let’s start by mapping out what we need to do in order to fufill out objective:
Expansion
- Wait for the user to hover over one of the main links
- Show the close X
- Make sure no main links have the active class (the class that will make their background match the sub link’s background)
- Add the active class to the main link that is hovered over
- Animate the height of the top bar to 40px
- Make sure no sub links are showing by hiding all sub links
- Show the sub-links of the main link that is being hovered over
Contraction
- Wait for the close X to be clicked
- Hide all sub links
- Remove the active class from all main links
- Animate the height of the sub link bar back to 10px
- Hide the close X
The HTML
There are already many great tutorials on this site for learning the basics of HTML & CSS, so for this tutorial I will assume you already know the basics. I’ll skip going into detail for this part:
For the actual page content, we will just use an image of the content to bypass the loss of quality that goes along with web text. This makes the HTML pretty simple:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>A Different Top Nav</title>
</head>
<body>
<div id="sub-link-bar"> </div>
<!-- End sub-link-bar -->
<div id="wrap">
<div id="main-handle">
<div class="roundfg">
<ul id="main-nav">
<li><a class="main-link" href="http://net.tutsplus.com/">Home</a>
<ul class="sub-links">
<li><a class="main-link" href="http://net.tutsplus.com/">Home</a></li>
</ul>
</li>
<li><a class="main-link" href="http://net.tutsplus.com/category/tutorials/">Tutorials</a>
<ul class="sub-links">
<li><a href="http://net.tutsplus.com/category/tutorials/design-tutorials/" title="View all posts filed under Design">Design</a> </li>
<li><a href="http://net.tutsplus.com/category/tutorials/html-css-techniques/" title="View all posts filed under HTML & CSS">HTML & CSS</a> </li>
<li><a href="http://net.tutsplus.com/category/tutorials/other/" title="View all posts filed under Other">Other</a> </li>
<li><a href="http://net.tutsplus.com/category/tutorials/php/" title="View all posts filed under PHP">PHP</a> </li>
<li><a href="http://net.tutsplus.com/category/tutorials/ruby/" title="View all posts filed under Ruby">Ruby</a> </li>
<li><a href="http://net.tutsplus.com/category/tutorials/site-builds/" title="View all posts filed under Site Builds">Site Builds</a> </li>
<li><a href="http://net.tutsplus.com/category/tutorials/tools-and-tips/" title="View all posts filed under Tools & Tips">Tools & Tips</a> </li>
<li class="cat-item cat-item-35"><a href="http://net.tutsplus.com/category/tutorials/wordpress/" title="View all posts filed under WordPress">WordPress</a> </li>
</ul>
</li>
<li><a class="main-link" href="http://net.tutsplus.com/category/articles/">Articles</a>
<ul class="sub-links">
<li ><a href="http://net.tutsplus.com/category/articles/general/" title="View all posts filed under General">General</a> </li>
<li><a href="http://net.tutsplus.com/category/articles/interviews/" title="View all posts filed under Interviews">Interviews</a> </li>
<li><a href="http://net.tutsplus.com/category/articles/news/" title="View all posts filed under News">News</a> </li>
<li><a href="http://net.tutsplus.com/category/articles/web-roundups/" title="View all posts filed under Web Roundups">Web Roundups</a> </li>
</ul>
</li>
<li><a class="main-link" href="http://net.tutsplus.com/category/freebies/">Freebies</a>
<ul class="sub-links">
<li><a href="http://net.tutsplus.com/category/freebies/books/" title="View all posts filed under Books">Books</a> </li>
<li><a href="http://net.tutsplus.com/category/freebies/icons-freebies/" title="View all posts filed under Icons">Icons</a> </li>
<li><a href="http://net.tutsplus.com/category/freebies/lightboxes/" title="View all posts filed under Lightboxes">Lightboxes</a> </li>
<li><a href="http://net.tutsplus.com/category/freebies/others/" title="View all posts filed under Others">Others</a> </li>
<li><a href="http://net.tutsplus.com/category/freebies/plugins/" title="View all posts filed under Plugins">Plugins</a> </li>
<li><a href="http://net.tutsplus.com/category/freebies/themes/" title="View all posts filed under Themes">Themes</a> </li>
<li><a href="http://net.tutsplus.com/category/freebies/tooltips/" title="View all posts filed under Tooltips">Tooltips</a> </li>
</ul>
</li>
<li><a class="main-link" href="http://net.tutsplus.com/category/videos/">Videos</a>
<ul class="sub-links">
<li><a href="http://net.tutsplus.com/category/videos/screencasts/" title="Screencasts">Screencasts</a> </li>
</ul>
</li>
<li><a class="main-link" href="http://net.tutsplus.com/about">About</a>
<ul class="sub-links">
<li><a href="http://net.tutsplus.com/about/" title="About">About</a></li>
<li><a href="http://tutsplus.com/join/" title="Join Plus">Join Plus</a></li>
<li><a href="http://net.tutsplus.com/about/rss-feeds/" title="RSS Feeds">RSS Feeds</a></li>
<li><a href="http://net.tutsplus.com/about/submissions/" title="Submit a Freebie">Submit a Freebie</a></li>
<li><a href="http://net.tutsplus.com/about/terms/" title="Terms">Terms</a></li>
<li><a href="http://net.tutsplus.com/about/write-a-tutorial/" title="Write a Tutorial">Write a Tutorial</a></li>
</ul>
</li>
<li><a class="close" title="Click to Collapse" href="#">X</a></li>
</ul>
</div>
<!-- End roundfg -->
<b class="round"> <b class="round5"></b> <b class="round4"></b> <b class="round3"></b> <b class="round2"><b></b></b> <b class="round1"><b></b></b></b> </div>
<!-- End main-handle-->
</div>
<!-- End wrap -->
</body>
</html>
The CSS
The CSS is pretty simple too. Since this tutorial does not focus on HTML or CSS, if you have a specific question about it, you can drop me a line in the comments below.
html, body {
background: #2d2620;
text-align: center;
margin: 0px;
height: 100%;
width: 100%;
}
#wrap {
margin-left: auto;
margin-right: auto;
width: 900px;
position: relative;
background: url(body.png) center no-repeat;
min-height: 600px;
}
#body-image {
margin-top: 60px;
}
#main-nav {
margin: 0px 0px 0px 2px;
text-align: left;
min-height: 25px;
padding-top: 10px;
padding-left: 0px;
}
#main-handle {
width: 605px;
float: right;
margin-top: -1px;
}
#main-nav li {
display: inline;
list-style: none;
}
#main-nav li a {
margin-right: 5px;
font-size: 15px;
text-decoration: none;
color: #f2f2f2;
font-family: Arial, Helvetica, sans-serif;
text-transform: uppercase;
font-weight: bold;
padding: 10px;
outline: 0;
position: relative;
top: -2px;
}
#main-nav li a:hover, #main-nav li a.active {
background: #514539;
}
#sub-link-bar {
background: #514539;
min-height: 10px;
border-bottom: #645546 1px solid;
}
.sub-links {
display: none;
position: absolute;
width: 100%;
top: -30px;
text-align: left;
left: 0px;
}
#main-nav li .sub-links li a:hover{
background: #2d2620;
}
#main-nav li a.close{
display: none;
position: absolute;
}
#main-nav li a.close:hover{
background: #900;
}
Rounded Corners
For this example, we’d also like to make the bottom corners rounded. There are many different solutions to this dilema, including using images, javascript, CSS or ususally a combination of the aforementioned. For this example, I’d like to achieve the corners using only CSS. Although CSS3 offers us an easy solution, it is still not cross browser compatible. So for this example, we are going to use an online service called Spiffy Corners. Spiffy Corners generates all the code for us. It’s pretty cool. We input the radius of the corners, the desired class name, and the background, and foreground color-it does the rest.

Here’s the code it spitted out for us:
<style type="text/css">
.round{display:block}
.round *{
display:block;
height:1px;
overflow:hidden;
font-size:.01em;
background:#645546}
.round1{
margin-left:3px;
margin-right:3px;
padding-left:1px;
padding-right:1px;
border-left:1px solid #443a30;
border-right:1px solid #443a30;
background:#56493c}
.round2{
margin-left:1px;
margin-right:1px;
padding-right:1px;
padding-left:1px;
border-left:1px solid #322a23;
border-right:1px solid #322a23;
background:#594c3e}
.round3{
margin-left:1px;
margin-right:1px;
border-left:1px solid #594c3e;
border-right:1px solid #594c3e;}
.round4{
border-left:1px solid #443a30;
border-right:1px solid #443a30}
.round5{
border-left:1px solid #56493c;
border-right:1px solid #56493c}
.roundfg{
background:#645546}
</style>
Get the Code: HTML
<div>
<b class="round">
<b class="round1"><b></b></b>
<b class="round2"><b></b></b>
<b class="round3"></b>
<b class="round4"></b>
<b class="round5"></b></b>
<div class="roundfg">
<!-- content goes here -->
</div>
<b class="round">
<b class="round5"></b>
<b class="round4"></b>
<b class="round3"></b>
<b class="round2"><b></b></b>
<b class="round1"><b></b></b></b>
</div>
Script Time
Let’s Go Over the Functionality Again:
-
Expansion
- Wait for the user to hover over one of the main links
- Show the close X
- Make sure no main links have the active class (the class that will make their background match the sub link’s background)
- Add the active class to the main link that is hovered over
- Animate the height of the top bar to 40px
- Make sure no sub links are showing by hiding all sub links
- Show the sub-links of the main link that is being hovered over
Contraction
- Wait for the close X to be clicked
- Hide all sub links
- Remove the active class from all main links
- Animate the height of the sub link bar back to 10px
- Hide the close X
How We Are Going to Accomplish These Things
Add the Listener:
We put the handle on hover listener inside the on DOM reading function:
$(document).ready(function(){
$("#main-nav li a.main-link").hover(function(){
});
});
Show the Close X
To show the X, we will use the fadeIn() function:
$("#main-nav li a.close").fadeIn();
Make sure no main links have the active class
To do this, we will remove the .active class from all main links
$("#main-nav li a.main-link").removeClass("active");
Add the active class to the element being hovered on
By using the “this” selector we can select the current element we are talking about. Since we are inside a hovering listener, it will add the class to the specific element that is being hovered on.
$(this).addClass("active");
Animate the height of the top bar to 40px
We will use the animate() function for this.
$("#sub-link-bar").animate({
height: "40px"
});
Make sure no sub-links are showing
To do this, we will use the same technique we used to remove the active class from all elements. Only this time, we will hide all sub-link lists.
$(".sub-links").hide();
Show the correct set of sub-links
To do this, we will select the sibling element of the hovered element and show the sibling list.
$(this).siblings(".sub-links").fadeIn();
Contraction
Now let’s add the ability to close the bar again. For this example, I’ve decided to include an X that will collapse the bar. For your example however, you could choose any method you think is the most intuitive and functional.
Wait for the X to be clicked
To do this, we will set an event listener that waits for the X to be clicked and then does something.
$("#main-nav li a.close").click(function(){
});
Remove the active class from all main links
The first thing we want to do after the X is clicked is remove the active class from any main link, because when the menu is collapsing, nothing should be selected.
$("#main-nav li a.main-link").removeClass("active");
Hide all sub-links
Now that the bar is about to collapse, we need to hide all of the sub-links.
$(".sub-links").fadeOut();;
Animate the Top bar back to 10px
Now we need to minimize the bar back to 10px
$("#sub-link-bar").animate({ height: "10px" });
Hide the X again
Now that the panel is collapsed, the user should not see an option to close the bar anymore. So we need to hide it again.
$("#main-nav li a.close").fadeOut();
The Whole Script
Now that we’ve gone over the script in detail, let’s take a look at the whole thing:
$(document).ready(function(){
$("#main-nav li a.main-link").hover(function(){
$("#main-nav li a.close").fadeIn();
$("#main-nav li a.main-link").removeClass("active");
$(this).addClass("active");
$("#sub-link-bar").animate({
height: "40px"
});
$(".sub-links").hide();
$(this).siblings(".sub-links").fadeIn();
});
$("#main-nav li a.close").click(function(){
$("#main-nav li a.main-link").removeClass("active");
$(".sub-links").fadeOut();
$("#sub-link-bar").animate({
height: "10px"
});
$("#main-nav li a.close").fadeOut();
});
});
We’re Done
Congratulations! You have created a horizontal navigation system that will stand out on your site as different! I hope you have enjoyed the tutorial and found it useful in learning more about how to use jQuery for practical applications. If you have any questions or comments be sure to leave them in the comments below! I’d love to hear from you!
- Follow us on Twitter, or subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.





I love menu tips. Nothing makes or breaks a site like the menu.
Clicking the ‘Desired effect’ images to see the full size version results in a 404 error.
The following errors show up in Firefox 3.5.1′s error console when viewing the demo:
Blocking cross site Javascript served from http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js with wrong mimetype text/x-c and included by http://nettuts.s3.amazonaws.com/386_navigation/top-nav-demo/index.html
Error: $ is not defined
Source File: http://nettuts.s3.amazonaws.com/386_navigation/top-nav-demo/index.html
Line: 129
Hi Perseco,
From the error you copied over, it seems that your specific browser settings blocked the jQuery because it was from another site. Thus since jQuery was not loaded, all of the $ signs to begin jQuery functions went unrecognized because jQuery was never loaded.
Absolutely love it, thanks so much for this post.
I think I will use this for a project in the future.
nice menu!
I like the *effect* very much, but the thing is, I’m not so sure where it can be used. I woudn’t like having to browse a website with that sort of navigation.
I’m not fan of this. I would have put the sliding part down the main bar, that’d have been more ergonomic.
You should use hoverIntent because now when you hover an item and try to go to a submenu item it’s easy to close the menu again… Just to make sure that the user is actually hover:ing over that item and not just passing by. :)
It doesn’t like Firefox 3.5.1.
Could you use image replacement for the buttons?
And could you make a vertical menu like this-it seems like people are only making horizontal menus in this style these days.
Cool Navigation :)
Cannot work fine in IE6!!
sometimes one sublink shows over another sublink, what to do? I want to use this navigation in my next project
Very creative way to rework a navigation, looks incredible and works exceptionally well. Thank you for the tutorial.
Wow thats awsome!
Im not going to use it personally but i think it looks amazing!
NICE TUT!
That is a amazing work and i use it well, but i want to change some thinks and do not how i can do this.
I want to hide two #containers with the JS code, because i want to add a second div in the hidden div.
Can anybody explain to me, in which way i have to change the JS code to get it?
Thanks a lot and best regards
Dennis
For anyone else who may have an issue with a “handler is undefined” error being thrown. The issue is with the hover function in menu.js. The hover event takes 2 parameters and only one is defined. I just added a blank stub function to the event and the error went away.
The new code is:
$(document).ready(function(){
$(“#main-nav li a.main-link”).hover(function(){
$(“#main-nav li a.close”).fadeIn();
$(“#main-nav li a.main-link”).removeClass(“active”);
$(this).addClass(“active”);
$(“#sub-link-bar”).animate({
height: “40px”
});
$(“.sub-links”).hide();
$(this).siblings(“.sub-links”).fadeIn();
}, function(){});
$(“#main-nav li a.close”).click(function(){
$(“#main-nav li a.main-link”).removeClass(“active”);
$(“.sub-links”).fadeOut();
$(“#sub-link-bar”).animate({
height: “10px”
});
$(“#main-nav li a.close”).fadeOut();
});
});
Hey, thanks for this awesome menu.
Is it possible to make the submenu with a downward movement instead of upwards?
thanks
I to love this menu and looking for the desired effect for the sub menu to be below the main menu and push it up rather then the way it is now. has anyone accomplished this?
Yes. It’s different!
Nice, but… doesn’t work IE8 :(
hehehe…
I like it, however I do not want the user to click close to hide, it should hide itself when one roll out the menu. Any suggestions?
I would love to see an example where the sub-menu disappears when you ‘mouseout’ rather than clicking the X. Has anyone accomplished this?
Really really nice.
But could I remove the option for closing, by eliminating the X?
Am I the only one having trouble with the menu titles stacking up on each other?
Aloha,
I have tried to use this menu on this website (http://www.valleyisleaquatics.com) and it works wonderfully when it is by itself. As soon as I put text under it or use PHP to call it in with the content page and footer page, it makes all the links not function in Firefox and Chrome, as well as the 1st link in IE8. I have tried backing up and starting over many times, and it still breaks all the page’s links. There must be something I am missing, a snipet, a work-around, a hack or something. I have been trying to fix this error for a couple of months to no avail, so any help here would be more than appreciated!=)
Mahalo,
Kelly
I tried and tried to get this to work in Chrome and Firefox to no avail! Anytime there is a link below this, it blocks the link from being active. I have tried changing everything I can think of; rewriting from the beginning; putting it all on one page rather than rending via PHP, but nothing works. I am finally giving up on this menu, although I thought it was cool, if all the links below it don’t work, then it is not very useful.
For those who were having issues with the submenu links stacking up on each other and messing everything up, hoverIntent was the way to go!
Many thanks to Connor for this awesome menu! I had the stacking issue as well so I decided to tweak it a bit and added hoverIntent to the code.
Here you go if anyone is interested
$(document).ready(function() {
$(“#main-nav li a.main-link”).hoverIntent(goUp, doNothing)
});
function goUp(){
$(“#main-nav li a.close”).fadeIn();
$(“#main-nav li a.main-link”).removeClass(“active”);
$(this).addClass(“active”);
$(“#sub-link-bar”).animate({
height: “40px”
});
$(“.sub-links”).hide();
$(this).siblings(“.sub-links”).fadeIn();
};
function doNothing() {};
$(“#main-nav li a.close”).click(function() {
$(“#main-nav li a.main-link”).removeClass(“active”);
$(“.sub-links”).fadeOut();
$(“#sub-link-bar”).animate({
height: “10px”
});
$(“#main-nav li a.close”).fadeOut();
});
It appears I didn’t realize the click function was left out so placing it in the goUp function allows the menu to work beautifully.
Also, don’t forget to load the hoverIntent plugin right after jquery for this to work.
Good, but poor documentation. If I want the sub nav bar to appear BELOW themain links, how can one do that?
Also, a fully worked example of this working with auto-close instead of [X] would be useful. Shame the thing is not easily configurable; my clients hate the sub-menu on top, so it can’t be used in a real life client website.
Dear,
Your tutorial is so great but I am looking for the way to style wordpress 3.04 menu, not the simple html like your example. Can you teach me how to do this?
Thank you,
Can you integrate this menu with wordpress???
thank you
Question: If instead of showing the X, I want it to collapse on a timed instance, how do I do that? I’ve tried:
$(document).ready(function(){
$(“#main-nav li a.main-link”).hover(function(){
$(“#main-nav li a.close”).fadeIn();
$(“#main-nav li a.main-link”).removeClass(“active”);
$(this).addClass(“active”);
$(“#sub-link-bar”).animate({
height: “40px”
});
$(“.sub-links”).hide();
$(this).siblings(“.sub-links”).fadeIn();
setTimeout(“timeMsg()”,5000);
});
function timeMsg() {
$(“#main-nav li a.main-link”).removeClass(“active”);
$(“.sub-links”).fadeOut();
$(“#sub-link-bar”).animate({height: “10px”});
$(“#main-nav li a.close”).fadeOut();
}
(for instance) along with multiple variations and it still doesn’t seem to work…what am I missing?
Question:
How can i do to make lighted my sub-link when i’m in a subpage?
It’s quite confusing when i’m surfing in sub-pages and you don’t know where u are without the sub-menu.
Thank you very much!
Great job!
Thanks so much for the menu, its excellent. However, I cant seem to get the code very well. Please, can you arrange the code in simple terms: which one should be in the head, body or a separate file. Please, reply. Thanks
Very nice menu.
I am using it withing an html box in a master-frame but when adding a lightbox fancybox, the gallery would work… the static image opens in the browser.
Is it maybe conflicting?
Beginner here
light box code
$(document).ready(function()
{
$(“a[rel^='PhotoGallery1']“).fancybox({});
});
any help please?
sorry I meant the gallery would NOT work…
$(document).ready(function()
{
$(“a[rel^='PhotoGallery1']“).fancybox({});
});
Awesome! How can I make the sub menu stay up when it goes to its pages?
Thanks for the source code. I was looking for it. I am using it on my blog..
Quite nice, but I note there are still a few bugs, as pointed out by other comments…
Great work guys keep it up… very very useful, master box is the way forward !
Thanks Guys
Hello guys,
I have a small problem with the display on IE9, the menu keep flashes when mouse over, is there a solution for it?
Thank you in advance