Grow your CSS skills. Land your dream job.

Learning jQuery: Fading Menu – Replacing Content

Published by 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 );
	
});

Comments

  1. Nice Chris. In FF 2 the cursor is default on hover though. Maybe a quick cursor:pointer can be thrown into the CSS.

  2. Permalink to comment#

    i like jQuery
    cheers mate

  3. Flavia
    Permalink to comment#

    This is truly nice, Chris.
    Now I’ve got to come up with a new project to experiment with jQuery.
    And it’s your fault.

    …and I thank you – in uppercase – for this :)

  4. Romz
    Permalink to comment#

    Hello Chris,

    Maybe a better way to perform your animation :
    $(document).ready(function(){
    $(“#page-wrap div.button”).click(function(){

    if($(this).css(“opacity”) != “1″)
    {
    $(this).actualBtn.animate({
    opacity: 1,
    borderWidth: 5
    }, 600 );
    }

    $(this).siblings().animate({
    opacity: 0.5,
    borderWidth: 1
    }, 600 );

    });
    });

    You probably have to do some enhancements to filter the showed content div but it’s not a big deal for you I guess.
    If you want, I’ll do it

  5. Sweet. I’m in the process of learning jQuery myself so glad you’re doing some here

  6. Nice work Chris. My only suggestion would be to speed up the duration. Awesome though!

  7. Permalink to comment#

    jQuery is by far my preferred javascript library of choice and here is another example of why. Well done.

  8. Eoin
    Permalink to comment#

    Hmm, the content slides up and down with the thickness of the underlining black bar, in Firefox at least.

  9. Thanks for another good jQuery post.

  10. Nice post Chris, I would also suggest maybe tying in the history plugin for jquery so that you can still use the next and back buttons.

    Your skills are improving :)

  11. Steve

    Anyone know how to fade in a background image on MouseOver on a LI element, and obviously fade out the background on MouseOut? I’ve been searching for jQuery code, and all I found was one that dealt with color only.

  12. Jason
    Permalink to comment#

    The border “jumps” the first time you select a button in FF. Any ideas how to fix that?

  13. Jason
    Permalink to comment#

    What about internet explorer? It doesn’t function quite right there. You have to click twice for things to start working.


    Jason

  14. Rob
    Permalink to comment#

    If the colours are changed for the text in the css, when returning in Firefox and Safari (possibly IE), the text’s opacity is down. Any ideas?

  15. good work!
    i am looking for a fade for dynamic content. i mean, i am loading external content from external serverside file in a div and this loading should be fading when loading. is there any work like what i want?

  16. Permalink to comment#

    Jquery really help us alot man… I mean for web designer like me.. zero knowledge in JAVA but hey!~ Jquery do all the neatto effects and stuff!!!
    Thanks for sharing this… (salute)

  17. Zac Foreman
    Permalink to comment#

    Love what you have done here great job and thanks for sharing. One thing though, I am new to this and I was wondering when I put a div (Nivo Slider) inside of the div id=”home” on page load it shows the content but when i click div id=”about” then back to the home tab it does not show the content. How can I fix this?

    • Zac Foreman
      Permalink to comment#

      I can send you my html and css if you would like and it would help.

Leave a Comment

Current day month ye@r *

*May or may not contain any actual "CSS" or "Tricks".