Hover Menu

I’ve been a longtime user of moo.fx and then mootools before I was introduced to jQuery. I’ve never written about it, but I was immediately a fan. I love the way the scripts are really as unobtrusive as advertised. I was meddling with it recently, and came across an issue. jQuery’s animate (documentation) function is awesome, but it only animated parameters that accept numeric values. Think fontSize or borderWidth but not backgroundColor.

Mootools has this down. There’s a beautiful demonstration in the documentation that has a menu that cleanly animates both numeric and non-numeric values. A little perturbed, I started writing a plugin for jQuery to solve this before I decided to check the impressive list of already-existing plugins. I found Interface elements.

The solution is beautiful: ifx.js from the plugin completely overrides the animate function but enhances it. There are multiple new features, but the biggest one is that you can now animate across parameters like backgroundColor.

You’re going to need jQuery and ifx.js from Interface elements. The demonstration uses the latest versions of both as of this writing, with jQuery at v1.2.3 and Interface elements at v1.2. Before we continue, go and view the demonstration now.

The markup is just a simple list with a few placeholder elements. I imagine this could be used as a eye-catching menu.

<ul id="hover-menu">
    <li>menu item</li>
    <li>menu item</li>
    <li>menu item</li>
    <li>menu item</li>
    <li>menu item</li>
</ul>

The CSS to style this is again, just placeholder to demonstrate the effect:

#hover-menu {
    margin: 0;
    padding: 0;
}

#hover-menu li {
    display: block;
    margin: 0;
    padding: 6px;
    width: 120px;
    background: #333;
    color: #888;
}

Now the magic happens. First, here’s the Javascript that makes everything work:

<script type="text/javascript" charset="utf-8">
  $(document).ready(function() {
    $("#hover-menu > li").hover(function() {
      $(this).animate({
        marginLeft:"6px",
        color:"#ff8",
        backgroundColor:"#666"
        }, 200);
    }, function() {
      $(this).animate({
        marginLeft:"0",
        color:"#888",
        backgroundColor:"#333"
        }, 200);
    });
  });
</script>

A few things to point out here:

  • We’re selecting all li elements that are children of #hover-menu. This is so that we can create lists elsewhere on the same page without having the effect.
  • The hover function I’ve used here is stock jQuery, and takes two functions as parameters. The first is what happens on mouseover, and the second is what happens on mouseout. Take a look at the code and you’ll see I am essentially reverting back to the style elements that were originally in the CSS on mouseout.
  • I had a bit of trouble getting the function to animate em units. It works perfectly with px, but if you want to use em you need to increase the value by a factor of 10 (the demonstration does this). I have no idea why—let me know if you figure out what I am overlooking.
  • You’ll obviously want to change all the parameters in both Javascript and CSS to your liking. Again, be sure to animate to your default CSS values in the second parameter of the hover function.

And there you have it, a direct replica of the aforementioned mootools demonstration. I actually prefer this script to the mootools implementation, both aesthetically and pragmatically. I also find that the end result is a little smoother—run your mouse quickly over both and you’ll find that the jQuery implementation handles very smoothly, whereas the animation of the mootols implementation stutters sometimes. Feel free to use the code as you please, and if you haven’t done so already, check out the demonstration. Enjoy!

—★—

« Tinkering with NodeBox | Google App Engine »