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.
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="https://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.
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.
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!
I have found multiple tuts online, this is the easiest and best to follow. Thanks Chris and Liam!
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.
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?
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!
@Jesse
I am seeing the same problem. I am on mac using FF3. I don’t see the white color on Safari.
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'));
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
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.
Great tut thanks alot, getting a better understanding of the jQuery library.
Brilliant, I just employed this on my site navigation last week. Definately the future.
@oshouip, not sure if this is how chris implemented it, but try looking at the scrollTo and localScroll plugins for jQuery
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!
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.
@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
Thanks for this wonder jquery menu. I’ve downloaded it and will use it in my new projects. :)
Good menu. But too bad it’s in jQuery rather than Prototype or MooTools
It reminds me of those hideous Frontpage-style java powered buttons.
It definitely isn’t the future…
Nice menu, not sure I’d use it but nice all the same.
Man thanks for such a explanatory tutorial with the note that is so help Liam!!!
Please keep the Jquery Coming…
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?
Can anyone make to degrade gracefully without js?
@kidvector,
i think you’d just want to animate the opacity property in that instance.
Tks man, nice article.
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.
I can’t get it working either
Great tool, but it doesn’t seem to load fully each time you visit a page. Sometimes only the top half of the background time loads. Any ideas how to make it load faster & completely?