Create an Attractive jQuery Menu with Fadein and Fadeout Effect

Written by Kevin Liew on 24 Jul 2009
369,922 Views • Tutorials

Introduction

I got this tutorial request from a reader, if you have any request at all, please contact me, give me some suggestions for the upcoming tutorial! :)

Apparently, I have seen this kind of menu before, in Dragon Interactive . During the implementation, I was having a bit of problem, I thought it's just a simple fadein and fadeout effect, but it actually required a lot of CSS works and the right images.

Fade in menu Preview

1. HTML

HTML is very simple, just a list of links. :)

<ul id="navMenu">
	<li><a href="#">Test 1</a></li>
	<li><a href="#">Test 2</a></li>
	<li><a href="#">Test 3</a></li>
	<li><a href="#">Test 4</a></li>
	<li><a href="#">Test 5</a></li>
	<li><a href="#">Test 6</a></li>
</ul>

2. CSS

CSS is little bit complicated this time, therefore, I have put a lot of comments. I hope it will explain everything you need to know.

body {
	background:#222;	
}

#navMenu {
	margin:0; 
	padding:0;
	list-style:none;	
	font-family:arial;
	text-align:center;
	line-height:60px;
}

	#navMenu li {
		float:left;	
		
		/* default background image	*/
		background:url(default.jpg) no-repeat center center;	
		
		/* width and height of the menu item */
		width:120px;							
		height:70px;
		
		/* simulate pixel perfect using border */
		border-left:1px solid #111;				
		border-right:1px solid #333;
		border-top:1px solid #555;
		border-bottom:1px solid #333;
		
		/* must set it as relative, because .hover class top and left with absolute position will be positioned according to li.	*/
		position:relative;			
	}

	#navMenu li a {
		/* z-index must be higher than .hover class */
		z-index:20;				
		
		/* display as block and set the height according to the height of the menu to make the whole LI clickable	*/
		display:block;	
		height:70px;
		position:relative;
		color:#777;
	}

 	#navMenu li .hover {
 		/* mouseover image	*/
		background:url(over.jpg) no-repeat center center;		

		/* must be postion absolute 	*/
		position:absolute;	
		
		/*	width, height, left and top to fill the whole LI item	*/
		width:120px;	
		height:70px;
		left:0; 
		top:0;	
		
		/* display under the Anchor tag	*/
		z-index:0;		
		
		/* hide it by default	*/
		display:none;	
	}	

	#navMenu li.selected {
		/* selected image	*/
		background:url(selected.jpg) no-repeat center center;	
	}

3. Javascript

We are using the jQuery built-in fade in and face out effect. First of all, we need to append the div.hover to the list. After that, just a normal mouse hover event with the fadein and fadeout transition.

	
$(document).ready(function () {

	//Append a div with hover class to all the LI
	$('#navMenu li').append('<div class="hover"><\/div>');


	$('#navMenu li').hover(
		
		//Mouseover, fadeIn the hidden hover class	
		function() {
			
			$(this).children('div').stop(true, true).fadeIn('1000');	
		
		}, 
	
		//Mouseout, fadeOut the hover class
		function() {
		
			$(this).children('div').stop(true, true).fadeOut('1000');	
		
	}).click (function () {
	
		//Add selected class if user clicked on it
		$(this).addClass('selected');
		
	});

});

Conclusion

This is it, I haven't tested it on IE6 (I don't have one :()... if you having problem with that, please let me know, hopefully I will able to find a way to solve it, or if you can come out with a solution that'd be highly appreaciated! :) Thanks.

Last but not least, I need your support :) If you like this article, please help me to promote it by adding this post to your bookmark. Or you can subscribe to my RSS for more jQuery tutorial and design inspiration posts! Thanks!

Demo Download
Join the discussion

Comments will be moderated and rel="nofollow" will be added to all links. You can wrap your coding with [code][/code] to make use of built-in syntax highlighter.

110 comments
webmaster 13 years ago
thx for this tut! i've been searching a long time but it is'nt as easy to implement with tables ..
Reply
Kevin Liew Admin 13 years ago
table is not the best way to use to implement navigation menu :)
Reply
Filip 13 years ago
hi - nice quick tutorial :) but i have one problem - when one of options get 'selected' it stays that way - even when im doing demo - how do i make that so only one will be selected?
Reply
Kevin Liew Admin 13 years ago
You will either need a cookie or use your server side language (php, asp) to determine the page you currently on and assign .selected class to the selected navigation item.
Reply
Filip 13 years ago
thx thx :)
Reply
tychonaut 13 years ago
Not necessarily....

if you give all of your pages a body class (ie <body class="home">, <body class="about">, <body class="contact"> etc...

.. then you make your nav menu with classes as well..

<ul class="nav">
<li class="home"><a href="#">HOME</a></li>
<li class="home"><a href="#">ABOUT</a></li>
<li class="home"><a href="#">CONTACT</a></li>
</ul>

..then you can do something like this...

ul.nav li {

background-image:url(../images/NORMALbackground.jpg);

}

body.home ul.nav li.home,
body.about ul.nav li.about,
body.contact ul.nav li.about
{

background-image:url(../images/SELECTEDbackground.jpg);

}

.. so those links will only have a "selected" background applied to them if they are children of a body with the same class (ie it is the "contact" link on the "contact" page)



I just stumbled in here so I don't know how that fits in with the rest of the tutorial, but it is how I get "YOU ARE HERE - style" links without resorting to server side stuff.
Reply
KK 13 years ago
its a good suggestion Kevin Liew, but can u tell me how can i make this happen when i use Master page in ASP.net 2.0
Reply
Kevin Liew Admin 13 years ago
tychonaut, it's basically the same concept using the server side language. I was assuming that the website is a dynamic generated content, so normally there will be only one template share by different pages. In that case, you really need to use server side language, eg set a class to the body tag or just put a selected class to the nav.

However, if all you page content are hardcoded, your solution will work. :)
Reply
xiaoming 13 years ago
beautiful
Reply
A Different Designer 13 years ago
Great tutorial, thank you.
Reply
Luc 13 years ago
Good solution, and it even works with buttons without pictures in background (in opposite to opacity change method).
But what about timing controll? I changed the values of fadeIn and fadeOut effects to 200 and 100 miliseconds but nothing has changed. It behaves like with original setup, 1000 miliseconds. Any Ideas?

Greets
Reply
Kevin Liew Admin 13 years ago
interesting, try this: http://api.jquery.com/fadeIn/ . Put slow or fast to see if it works.
Reply
Luc 13 years ago
I must add that I'm rather a beginner in javascript but I have noticed this issue only with this script. Other solutions like drop down menus or panels and sliders which I use works perfect with all modifications.

Now strings work correctly, fast = 200 ms, slow = 600 ms, if omitted the default duration of 400 ms is used.
As usual everything is in the documentation and I have forgotten about this:)

Thanks again!
Reply
Luc 13 years ago
Ok, I know what I screwed up. If you use the strings like fast or slow, you have put them in quotes: 'fast' ...
when you use direct numerical values, remember to remove quotes, in fact you have '1000' value on fadeIn and fadeOut it doesn't work properly, the default value is taken (i'm not sure if it is 600 ms?).

Greets!
Reply
Ricardo Zea 13 years ago
I suggest you add a ".stop(true, true)" in the last function where the fade out happens, otherwise, the animation will build up if the user hovers in and out of an element several times.

This is the line I'm referring to:

function() {
$(this).children('div').stop(true, true).fadeOut('1000');
});

This script rocks.
Reply
ashley 13 years ago
it doesnt work
Reply
Kevin Liew Admin 13 years ago
it works. make sure you have jquery framework installed properly. download the demo.
Reply
a 13 years ago
EF
Reply
Jeannie 13 years ago
Hi, this plug-in is exactly what I was looking for a week, but i can't get it to work!

Error message: "This file does not have a valid Header."

What do i need to do??

Thanks!

Reply
Kevin Liew Admin 13 years ago
that's weird Did the download version work for you?
Reply
bogomip 13 years ago
very nice tutorial and yes as was mentioned you do need to use the .stop() function. I have been coding for a great many years and it is good to finally see that there is another who shares their knowledge. :)
Reply
Kevin Liew Admin 13 years ago
Hi Bogomip, Thanks for the reminder :) I have updated the script.
Reply
Kurt 13 years ago
It seems there is a very basic property lacking: if I press a button it's becomes "highlighted" to indicate that it is selected; however if afterwards I press another button this one also becomes highlighted, whereas intuitively only one button should be highlighted at a time.
Reply
Kevin Liew Admin 12 years ago
Hi Kurt, well, the thing is, after you click on the menu, it should navigate to the new page hence the highlighted state should be cleared. Unless you wanna use this for an AJAX page, then you will need to remove the selected class first.
Reply
indoblogger.eu 12 years ago
great tutorial
Reply
laws 12 years ago
divs shouldnt be in <li> items wont validate....this is bullshit!
Reply
Shadowcodes 12 years ago
I don't see any "div's" in the html ???

What are you smokin ?
Reply