Learning jQuery: Fading Menu – Replacing Content

Chris Coyier //

Update January 2013: Best practice for this kind of this is detailed here.
Update May 2010: I'm considering this article deprecated. I have an updated article here, which covers this same type of material only with more features, updated technology, and better practices.

fadingmenu.png

The more I learn about jQuery, the more natural it feels. Probably because of how closely tied to CSS it is. From a design perspective, the syntax for jQuery is:

"When I do this, make the CSS do this."

The more common slogan is:

Find something, do something.

...which is also awesome.

So now instead of thinking about CSS as page layout and a way to style your page when it loads, you can use in animation and change it on-the-fly to react to events that happen on your page. Take for example a menu. You can take the "click" event that happens when clicking on a menu to do lots of stuff.

This example page has three menu items and three content areas: home, about, and contact. By default, the home button is selected, meaning that it's menu graphic is at full opacity and it's content area is shown:

#home {
	display: block;
	padding: 30px;
}
#home-button {
	opacity: 1.0;
	border-bottom: 1px solid black;
}

By default, the other menu items are faded and their content areas are hidden, like so:

#about {
	display: none;
	padding: 30px;
}
#about-button {
	opacity: 0.5;
	border-bottom: 1px solid black;
}

With jQuery, we can listen for that click event and then act accordingly. This is what we want to happen:

  • Fade IN the menu item being clicked on.
  • Fade OUT all other menu items.
  • DISPLAY the corresponding content area.
  • HIDE all other content areas.

Since the home button is active by default, let's look at the jQuery javascript for the about button:

<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
	$(document).ready(function(){
		$("#about-button").click(function(){ 
			$(this).animate({ 
				opacity: 1.0,
				borderWidth: 5
			}, 600 );
			$("#home")
				.css({
					display: "none"
				});
			$("#about")
				.css({
					display: "block"
				});
			$("#contact")
				.css({
					display: "none"
				});
			$("#home-button").animate({ 
				opacity: 0.5,
				borderWidth: 1
			}, 600 );
			$("#contact-button").animate({ 
				opacity: 0.5,
				borderWidth: 1
			}, 600 );
		});
	});
</script>

Your complete javascript code would have similar chunks for all three buttons. As I've mentioned before, I'm just learning here, so there is likely to be a way smarter way of writing this, but these are the basics and they work.

UPDATE: This is way smarter.

$("#page-wrap div.button").click(function(){
	
	$clicked = $(this);
	
	// if the button is not already "transformed" AND is not animated
	if ($clicked.css("opacity") != "1" && $clicked.is(":not(animated)")) {
		
		$clicked.animate({
			opacity: 1,
			borderWidth: 5
		}, 600 );
		
		// each button div MUST have a "xx-button" and the target div must have an id "xx" 
		var idToLoad = $clicked.attr("id").split('-');
		
		//we search trough the content for the visible div and we fade it out
		$("#content").find("div:visible").fadeOut("fast", function(){
			//once the fade out is completed, we start to fade in the right div
			$(this).parent().find("#"+idToLoad[0]).fadeIn();
		})
	}
	
	//we reset the other buttons to default style
	$clicked.siblings(".button").animate({
		opacity: 0.5,
		borderWidth: 1
	}, 600 );
	
});