Grow your CSS skills. Land your dream job.

Color Fading Menu with jQuery

Published by Guest Author

Editor's note: When I first pushed out this latest redesign for CSS-Tricks, it featured a simple color fading animation in the main navigation. Liam quickly noticed a flaw in the code I was using to do it, where if you very quickly moused back and forth over the menu items some of the transitional color would "stick". Liam generously rewrote the code to be a bit smarter for me, and I asked him to write this tutorial. Thanks Liam!

Hello, I am Liam Goodacre, and Chris has asked me to write a short jQuery tutorial on how to achieve fading hover effects. I will demonstrate how to perform colour and image merging. We will be using jQuery and the jQuery Colour plugin.

When I first wrote something like this, I set a background div to fade in on mouse hover, and fade out on mouse leave. I found that if I quickly moved my mouse over and out of the link, then the background kept flashing the same number of times as my mouse. I then told the animation to stop before I set new animations, this solved the problem, but produced a new one.

The new problem: if I did the same test (repeated mouse hovering), then the link's mouse out state, would slowly look the same as the hover state, therefore the background stopped fading out after a few times. I noticed that Chris had this same problem on his site.

I then had an idea; on mouse hover, if I stopped the current animation, and reset the background to be invisible, then fade it in, rather than starting it fading from its current state. This seems to have solved the problem.

View ExampleDownload Files

Ok then, let's get started...

What we need is a div containing two things; an anchor element and another div, which I will refer to as the subDiv. The subDiv will display the image that will fade in on mouse hover. The Anchor will overlap the subDiv and have a transparent background.

The HTML

We will add the subDiv to the div dynamically using jQuery, to reduce the ammount of html we need to write. This is helpful, when having multiple links like this.

This is our html code so far...

<div class="hoverBtn">
	<a href="http://css-tricks.com/">Go to CSS-Tricks</a>
</div>

We have a div with a class of hoverBtn containing and a link to CSS-Tricks.

The CSS

div.hoverBtn {
	position: 		relative;
	width: 			100px;
	height: 		30px;
	background:		#000 url(your_background_image.png) repeat-x 0 0 scroll;
}
div.hoverBtn a {
	position: 		relative;
	z-index: 		2;
	display: 		block;
	width: 			100px;
	height: 		30px;
	line-height: 		30px;
	text-align: 		center;
	color:			#000;
	background:		transparent none repeat-x 0 0 scroll;
}
div.hoverBtn div {
	display:		none;
	position: 		relative;
	z-index: 		1;
	width: 			100px;
	height: 		30px;
	margin-top: 		-30px;
	background:		#FFF url(your_hover_image.png) none repeat-x 0 0 scroll;
}

The subDiv is now positioned underneath the anchor, and I have applied background graphics to the div and the subDiv.

The JavaScript

I am going to assume you have a basic understanding of how to use jQuery, although, even if you don't, the code is pretty much self explanatory.

Here is our starting point...

//when the dom has loaded
$(function(){
	
});

I'm sure most of you are all fully aware, any code written within these two lines, will run as soon as the DOM has finished loading.

We now need to add the subDiv. Which we an accomplish by using the 'append' method of jQuery objects.

//when the dom has loaded
$(function(){
	//display the hover div
	$("div.hoverBtn").show("fast", function() {
		//append the background div
		$(this).append("<div></div>");
	});
});

I have wrapped the 'append' within the call-back of the show method, so that we can use 'this' to reference each div.hoverBtn element.

Now we need to code the link's hover event. We will fade the font colour, therefore we should specify a hover colour. We can also use the 'rel' attribute to store the initial colour of each anchor. This is useful for different coloured links.

var hoverColour = "#FFF";
//when the dom has loaded
$(function(){
	//display the hover div
	$("div.hoverBtn").show("fast", function() {
		//append the background div
		$(this).append("<div></div>");
		//on link hover
		$(this).children("a").hover(function(){
			//store initial link colour
			if ($(this).attr("rel") == "") {
				$(this).attr("rel", $(this).css("color"));
			}
			//fade in the background
			$(this).parent().children("div")
				.stop()
				.css({"display": "none", "opacity": "1"})
				.fadeIn("fast");
			//fade the colour
			$(this)	.stop()
				.css({"color": $(this).attr("rel")})
				.animate({"color": hoverColour}, 350);
		},function(){
			//fade out the background
			$(this).parent().children("div")
				.stop()
				.fadeOut("slow");
			//fade the colour
			$(this)	.stop()
				.animate({"color": $(this).attr("rel")}, 250);
		});
	});
});

So basically, what happens is;

  • A hover colour is declared
  • When the DOM has loaded...
  • A subDiv is appended to the hoverBtn div
  • On the hover event of the link:
    The initial colour is stored within the link's rel attribute
    The subDiv's animation is stopped
    It is hidden and then set to fade in
    The link's animation is stopped
    It's colour reset and set to fade to the hover colour
  • On the hover event's call-back:
    The subDiv's animation is stopped
    It is then set to fade out
    The link's animation is stopped
    It is then set to fade to it's initial colour

Further developments

You could try to improve this by dynamically loading the containing div. Which might also involve setting the containing div's size to that of the anchor element.

Comments

  1. Permalink to comment#

    Liam, looks really good to me, im trying to get more in to jquery seems a good route to take over some of the other libraries, i may implement this on my blog or experiment with it like you said.

  2. I love the tutorial. Thanks Chris and Liam! Just for the sake of sharing, I thought I’d share a similar tutorial that has some extra functionality – It allows for a CSS-Sprite backup plan should the end-user not have JS-enabled (who would do such a thing?). Dave Shea wrote about this idea on A List Apart – Check it out for yourself!

  3. Brian K
    Permalink to comment#

    I have found multiple tuts online, this is the easiest and best to follow. Thanks Chris and Liam!

  4. Permalink to comment#

    If the links in the menu have that nice fading effect, why does the search button on the sidebar lack the fader? I think the new design would feel better without such little Inconsistencies.

  5. Permalink to comment#

    Very nice tut. Easy to follow, and the final product is worth going through the process. Now I need to figure out how to implement this into my WordPress blog…any hints?

  6. Permalink to comment#

    When viewing the demo file, the first link hover state stays white for me the first time I mouse over it. It goes away after the first time. Weird. I dunno if I have something funky or not (XP/FF3). Thnx for the post!

  7. Permalink to comment#

    @Jesse

    I am seeing the same problem. I am on mac using FF3. I don’t see the white color on Safari.

  8. brad dunbar
    Permalink to comment#

    Great article Liam. The only question I have is why you used the “rel” attribute to store the color? Your markup is beautifully semantic other than this. Why not use the jQuery data function like so:

    // store
    $(this).data('color', $(this).css('color'));
    // retrieve
    $(this).css('color', $(this).data('color'));

  9. Thank you for all your comments everyone!
    @Gaber:
    Sorry I currently do not have any experience with WordPress but I will do soon, so I may have to get back to you with that.

    @jesse & @Benjamin:
    I have just noticed this too, it only seems to be happening on the online example, I doesn’t show a white block when running locally from my desktop… strange, I will look into why this is happening.

    @brad dunbar:
    Ah very interesting, I used the rel attribute as this is what Chris had been using so I just kinda adopted the method. I hadn’t heard that jQuery had a data method, I will use this in the future, thanks. I may also inform Chris to alter the tutorial so others may benefit from knowing this.

    –Liam

  10. Permalink to comment#

    Thank u very much, I hope u make a tutorial about the tabs in your side bar which contain the popular posts and featured posts, I like them too much and i cannot figure out who u did them.

  11. Great tut thanks alot, getting a better understanding of the jQuery library.

  12. Permalink to comment#

    Brilliant, I just employed this on my site navigation last week. Definately the future.

  13. Permalink to comment#

    @oshouip, not sure if this is how chris implemented it, but try looking at the scrollTo and localScroll plugins for jQuery

  14. Permalink to comment#

    Hi folks! This new menu looks really great. I have a question about jquery in general. I noticed that when I open my sites in IE, it always shows some alert popups for using jquey. Why does that hapeen? And why it’s doesn’t happen to you! Thank you!

  15. Permalink to comment#

    Thanx Chris and Liam very interesting. I will definitely try this later. @oshouip, Chris did a tutorial on NETTUTS on that sidebar. click
    Here to read the article. Hope that helps.

  16. Permalink to comment#

    @Gaber For WordPress you should include jQuery from their own library with wordpress special function. Then in wordpress you should use in the javascript ‘jQuery’ instead of ‘$‘. Check tut about this

  17. Permalink to comment#

    Thanks for this wonder jquery menu. I’ve downloaded it and will use it in my new projects. :)

  18. Permalink to comment#

    Good menu. But too bad it’s in jQuery rather than Prototype or MooTools

  19. Dave
    Permalink to comment#

    It reminds me of those hideous Frontpage-style java powered buttons.

    It definitely isn’t the future…

  20. Permalink to comment#

    Nice menu, not sure I’d use it but nice all the same.

  21. Man thanks for such a explanatory tutorial with the note that is so help Liam!!!
    Please keep the Jquery Coming…

  22. KidVector
    Permalink to comment#

    Hello again guys. I've got Matthew's suggestion working quite well (thanks Matthew) but again my knowledge is letting my down slightly. On the original state of my <ul> there is no background, I want it to fade to a colour, then on mouse out fade back to nothing, not to another colour. Does anyone have any suggestions as to how this could be achieved?

  23. elvisparsley
    Permalink to comment#

    Can anyone make to degrade gracefully without js?

  24. Permalink to comment#

    @kidvector,

    i think you’d just want to animate the opacity property in that instance.

  25. Permalink to comment#

    Tks man, nice article.

  26. ed
    Permalink to comment#

    Hi
    I am trying to use your JS with an accordion menu JS, But I am unable to get it working. The hover effect works but the accordion menu wont work open
    I have tried several thing but no luck. If you could point me in the right directions it would be much appreciated.

Leave a Comment

Current day month ye@r *

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