Loading...
February 2, 2011#

Using JQuery to animate our CSS dropdown menu

css-dropdown-animate

This tutorial continues on from the last and explains how to add menu animation for a slicker feel in just a few lines of code.

If you have not followed the last tutorial please do so because this is a follow-on: Create a CSS dropdown with unlimited submenus

Demo

click here

A small change to the CSS

Since we are using animation to show the menu we want the menu display by default to be off. So you can either remove the following hover events or simply change display:block to display:none (the lines are highlighted)

/* position the menu */
#nav { float:left; z-index:100; position:relative; }
/* first level */
#nav > li { float:left; list-style:none; font:20px "Arial Narrow", Arial, sans-serif; }
#nav > li > a { display:block; line-height:38px; padding:0 18px; color:#363636; text-decoration:none; }
#nav > li > a:hover, #nav > li .active { background-color:#363636; color:#fff; }
/* template for all lists below first */
#nav > li ul { display:none; position:absolute; float:left; width:10em; background-color:#666; }
#nav > li ul a { display:block; width:10em; color:#fff; padding:8px 20px; font-size:16px; text-decoration:none; }
#nav > li ul a:hover { background-color:#bc3030; color:#fff; }
/* second level */
#nav > li:hover > ul { display:block; }
/* all levels below second */
#nav > li li > ul { margin:-36px 0 0 10em; }
#nav > li li:hover > ul { display:block; }

Note: This will stop the dropdown working on a browser without javascript. But virtually anyone viewing the web with a graphics display has javascript turned on so I am not worried. If you want to get really anal about this you can associate the css hover pseudo class to a .class, and when JQuery is loaded remove this class with removeClass. I know we like to be perfectionists but I recommend you draw the line somewhere (i.e. javascript disabled browsers and IE6).

The JQuery part

Firstly, for a nice delay effect when the mouse leaves the particular menu part (ul) we can use a plugin called hoverIntent. Download and include this in your header below jquery.

On document ready event attach the hover event to the menu (timeout is the delay time to call the mouseout event after it has happened).

$("#nav li").hoverIntent({ over:menuAnimateIn, timeout:500, out:menuAnimateOut});

Add functions to handle these callbacks and the animation:

function menuAnimateIn() {
var ul = $(this).children("ul");
ul.animate({ width:"show" }, { duration:200 }).fadeIn();
};

function menuAnimateOut() {
var ul = $(this).children("ul");
ul.animate({ width:"hide"}, { duration:200 }).fadeOut();
};

What we are doing is:

  1. When a user hovers (mouseovers) a list (li) element, select the child menu (ul) element
  2. With this selection animate the width in and fade in at the same time

The mouseout event is the same but reversed (so animate the width to nothing and fade out).

Instead of fadeIn/fadeOut, why aren’t we using opacity:0/opacity:1 inside the animation function? This is because IE7 doesn’t like opacity and things break, with the fade function JQuery knows this and doesn’t apply it.

And that’s it! Pretty simple eh? Makes me wonder why so many JQuery menu plugins out there force you to use their cumbersome css when this animation code can be applied to any list based menu.

Download

Infinite CSS Dropdown Menu (196)

5 Comments

  1. Hi,

    Great tutorial! but somehow I accomplish to crash ie 9 with it if I rollover a couple of times… can it be done without hoverIntent? (other jquery in site seems stable).

    • Interesting though unfortunately I can’t replicate the bug in IE9

      • I only been able to replicate using win-64 and ie 9 Here is the link to the construction:
        http://derekdixon.co.uk/blue/

        Thanks for the reply and the initial test

      • Oh well, I disabled hoverintent and seems to work…

        Added a couple of rules to CSS to make it work without jquery:

        #nav li:hover ul ul, #nav li:hover ul ul ul, #nav li:hover ul ul ul ul{
        display:none;
        }
        #nav li:hover ul, #nav li li:hover ul, #nav li li li:hover ul, #nav li li li li:hover ul{
        display:block;
        }

        and then changed the javascript to just pure jquery functions
        //menu Jquery
        $(” #nav li”).hover(function(){
        $(this).find(‘ul:first’).css({visibility: “visible”,display: “none”}).slideDown(‘slow’).show();
        },function(){
        $(this).find(‘ul:first’).css({display: “block”}).slideUp();
        });

Leave a Comment