This page has tweets, likes, and +1's.

Animated Drop Down Menu with jQuery

by clark. 371 Comments

preview

View the effect

Drop down menus are a really convient way to fit a large menu into a really small initial space. For a long time people have just used a form element for standard drop downs, but with minimal effort you can create a much slicker effect using jQuery and CSS.


Step 1: The HTML

Before we can do anything, we need to link our CSS file and our jQuery file in the header our of HTML document:

<link href="css/style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="jsfiles/jquery.js"></script>

These two files will contain our styles and the javascript effect library (duh), but before we can style or animate anything, we need to build the list itself. We are going to use a simple unordered list:

<ul class="menu_body">
  <li><a href="#">About Us</a></li>
  <li><a href="#">Portfolio</a></li>

  <li><a href="#">Clients</a></li>
  <li><a href="#">Blog</a></li>
  <li><a href="#">Support Forums</a></li>

  <li><a href="#">Gallery</a></li>
  <li><a href="#">Contact Us</a></li>
</ul>

What we have here is as simple as it looks. We have an unordered list with the class of "menu_body". Inside we have multiple list items, each containing a navigation link. Next we need to add an image above the list. This image will serve as the list’s heading an all that is visible when the drop down is collapsed. It doesn’t have to be an image, this would work exactly the same with text to launch and collapse the menu, I just wanted something visual. If you want to use mine, you can find it here. With the image added we have our complete HTML:

<img src="images/navigate.png" width="184" height="32" class="menu_head" />

  <ul class="menu_body">
  <li><a href="#">About Us</a></li>
  <li><a href="#">Portfolio</a></li>

  <li><a href="#">Clients</a></li>
  <li><a href="#">Blog</a></li>
  <li><a href="#">Support Forums</a></li>

  <li><a href="#">Gallery</a></li>
  <li><a href="#">Contact Us</a></li>
</ul>

We need to give our image a class name, so we have something to reference by when we start our jQuery. I used the class "menu_head". Here is what we have so far, a completely unstyled list with an image on top:

Unstyled List


Step 2: The CSS

Next we need to give our list some style. First, lets do our top level styling:

body{background:#534741;font-family:Arial, Helvetica, sans-serif; font-size:12px;}
ul, li{margin:0; padding:0; list-style:none;}

Nothing too comples here, just setting a background color, font, and font size. Also, we are telling the list to have no padding, margin, or bullets. Now our list is just a heading and a neat column of links:

Some Style

Now we can style the heading image and each list item. Here is the CSS:

.menu_head{border:1px solid #998675;}
.menu_body {width:184px;border-right:1px solid #998675;border-bottom:1px solid #998675;border-left:1px solid #998675;}
.menu_body li{background:#493e3b;}
.menu_body li a{color:#FFFFFF; text-decoration:none; padding:10px; display:block;}

Here’s what we just did. We added a light tan border around the image "menu_head". On the unordered list "menu_body" we set a width (the same width as our image), and we added a light tan border to every side but the top (there will already be a line there since we have one around our image). We set a background color for each list item and we styled each link. Every link is now white, not underlines, has a nice amount of padding, and is set to a block display (this will make the whole box around the link clickable, not just the text itself).

Here is what our list should look now:

More Style


Step 3: The jQuery

Our first step will be to add the jQuery to tell the list items to alternate their background colors. In the head of your HTML document, add:

<script type="text/javascript">
$(document).ready(function () {$("ul.menu_body li:even").addClass("alt");
});

</script>

This is a basic jQuery function. When the document is ready, the function will add a special class of "alt" to each alternating row of our list. With the new classes applied, we can add a new CSS rule for the class "alt"

.menu_body li.alt{background:#362f2d;}

Now the rows will alternate between lighter and darker shades of brown, like this:

Row colors

Now the the list has the overall look that we want, we can go ahead and completely hide it with CSS. In the CSS rule for "menu_body" add the property "display:none;" like this:

.menu_body {display:none; width:184px;border-right:1px solid #998675;border-bottom:1px solid #998675;border-left:1px solid #998675;}

If you look at the page now, all you should be able to see if the heading image. For now, the menu has seemingly dissappeared. Time to bring it back with jQuery:

<script type="text/javascript">
$(document).ready(function () {
$("ul.menu_body li:even").addClass("alt");

$('img.menu_head').click(function () {

$('ul.menu_body').slideToggle('medium');

});
});
</script>

We added a new function that runs when the image with the class of "menu_head" is clicked. A click is just one of the events jQuery recognizes. You could also have the function run on mouseover, a key press, or numerous other things. When a click event is registered, jQuery will use the effect slideToggle on the unordered list with the class of "menu_body". jQuery has a large list of effects and various effect plugins, there is really no limit on how you can animate the list sliding open and closed. slideToggle allows you to set a speed, I chose medium, but you can also use "fast", "slow", or define a number in miliseconds.

The menu should now slide open and closed when you click on the heading image:

Animation

You could stop now and have a pretty decent animated menu, but with jQuery its very easy to add simple hover effects. First, we need to add some to our CSS:

.menu_body li a:hover{padding:15px 10px; font-weight:bold;}

This will do two things. When one of our links is hovered over, the padding on the top and bottom will be expanded to 15px (making each rolled over area taller and allowing the shift) and chaning the font weight to bold.

Next we can add some jQuery animation:

<script type="text/javascript">
$(document).ready(function () {
$("ul.menu_body li:even").addClass("alt");

$('img.menu_head').click(function () {
$('ul.menu_body').slideToggle('medium');
});

$('ul.menu_body li a').mouseover(function () {
$(this).animate({ fontSize: "14px", paddingLeft: "20px" }, 50 );
});


});
</script>

We’ve now added a mouseover function, one that runs anytime you mouseover any list item’s link within our unordered list. The function is set to run on "this" which just means the element will run the function on itself. We are using the jQuery effect animate, which allows for many different parameters, along with a duration of time to run them in. We’ve told the function to change the font size to 14px, change the padding-left to 20px, and to do both things in 50 miliseconds.

At this point, the menu can expand and collapse, and the mouseover effect on the links should be working. Now we just need to tell it to reverse the effect when we mouseoff a link. If we don’t tell it to reset each animation, the links will "stick" in their new font size and position. We, of course, want each link to snap back to its original position. We can easily do this like so:

<script type="text/javascript">

$(document).ready(function () {
$("ul.menu_body li:even").addClass("alt");
$('img.menu_head').click(function () {
$('ul.menu_body').slideToggle('medium');
});

$('ul.menu_body li a').mouseover(function () {
$(this).animate({ fontSize: "14px", paddingLeft: "20px" }, 50 );

});

$('ul.menu_body li a').mouseout.(function () {
$(this).animate({ fontSize: "12px", paddingLeft: "10px" }, 50 );
});
});
</script>

This is our last bit of jQuery. It is a function that runs whenever you mouseout of a list item’s link. It will reset the font to the original size (12px), change the padding-left back (to 10px). It will do both things in 50 miliseconds, the same speed as the first half of the animation.

Your menu should now be fully functional. It should be able to click open and close (in a sliding animation) and each link should animate when touched with the mouse (expanding the height, text size, and left-margin). I purposely tried to keep this menu light on images, but this simple effect is really easy to dress up some. For example, each link’s hover state could have an image background. Each image could be specific to each section for a really polished, intuituve menu and it would all fit into a small rectangle when not in use.

You can see the finished menu here.

Download the source files


Introducing QuikTab, a premium CMS style WordPress theme

QuikTab is a standards-compliant, one-page theme powered by WordPress and jQuery. You can buy it at ThemeForest for $12.

371 Responses to Animated Drop Down Menu with jQuery

  1. marc says:

    hi clark

    great site you did. now you’re employed, my question is: aside your work do you have some time free for coding or other projects?

    i’m from switzerland, send you greetings and hope to hear from you.

    marc

  2. jane says:

    this is great, but how would you use this as a horizontal menu? it breaks the menu items when you click on them, so the entire top level menu items move down below and open up.

  3. Animated Drop Down Menu - Con jQuery y Css says:

    [...] Animated Drop Down Menu with jQuery, un bonito menú desplegable basado en jQuery y Css. Muy práctico para ubicarlo en la sección superior de nuestro header, ya que ocupa muy poco lugar y a su vez lograra llamar la atención de los usuarios. Me recuerda mucho al menú de NETTUTS como a todos los de la red de Envato. [...]

  4. jeeremie says:

    Very nice menu indeed. It reminds me the top “Envato Networks” menu on Nettuts, PSDtuts and so on.

    I don’t really like the effects as you rollover a link though. I think that could be improved.

    Keep up the good work.

  5. Animated Drop Down Menu with jQuery | Exoxfire says:

    [...] Animated Drop Down Menu with jQuery, un bonito menú desplegable basado en jQuery y Css. Muy práctico para ubicarlo en la sección superior de nuestro header, ya que ocupa muy poco lugar y a su vez lograra llamar la atención de los usuarios. Me recuerda mucho al menú de NETTUTS como a todos los de la red de Envato. [...]

  6. Nick says:

    I wonder are there a code that if person unmouseover the menu. so it forces menu to close it istead of have to click it to close it?? im curious.

  7. awake says:

    i’ve not viewed the code yet, but I loved the demo.

    i was looking for somethign similar to what envato (netut guys) had.

    thanks a bunch

  8. Fede says:

    Hi, i have one “problem”. I cant make this to go over objects, images or flash, it’s moves all the content down. It is posible TO FLOAT OVER OBJECTS?
    Thanks in advance.

  9. kyle steed says:

    @Fede – if you wrap the whole thing in a div and set the div to float (left or right) then when it drops down it will float over your other content.

    The issue I’m having is I can’t get the javascript functions to work. Not even applying the “alt” class works. I just can’t seem to figure out what’s wrong. I did change the class names of my image and unordered list, but I made sure to change the class names in my javascript as well. Any ideas?

  10. kyle steed says:

    Ok. I finally got it to work. So I have a few constructive criticisms to offer those in the future.

    First, make sure you use double quotes when referencing your class names in the javascript. If you use single quotes the effect will not work.

    Also, make sure you use “normal” instead of “medium” for the slideToggle speed.

    You can learn more about slideToggle over at jQuery’s website:
    http://docs.jquery.com/Effects/slideToggle

  11. Binno says:

    How can i correct program mouseover and mouseout?

    $(‘img.menu_head’).mouseover(function () {
    $(‘ul.menu_body’).slideToggle(‘medium’);
    });

    $(‘img.menu_head’).mouseout(function () {
    $(‘ul.menu_body’).slideToggle(‘medium’);
    });

    When mouseout img.menu.head with mouse to scroll down, then must show on ul.menu.body so long as the mouse leave out ul.menu.body.

    Sorry, i write not good english. I come from Germany.

    Thanking you in advance for this problem solution!

  12. carl says:

    I have experimented with using this in a website(not online). It works great on the mac and in Firefox on the PC but…in IE7 the menu items/text jumps out in HUGE font sizes for a split-second before returning to to regular size.
    A jQuery thing? or perhaps confict with something else in my stylesheet?
    Any leads would be appreciated.
    Thanks.

  13. Scott Brooks says:

    Hi Clark,

    I love your Quick Tab theme and am thinking about purchasing it within the next couple of days. Would it be possible for me to implement the animated drop down on this them? A couple of the tabs would need to have a submenus. Thanks man.

  14. Dale says:

    I really like this menu but like some others I wanted it to function on mouseover and out.
    I am a beginner in javascript and jquery but by looking at another tutorial in jquery I have got it to work.

    $(document).ready(function() {
    $(“ul.menu_body li:even”).addClass(“alt”);
    $(‘.container’).hover(function() {
    $(‘ul.menu_body’).slideToggle(‘medium’);
    }, function() {
    $(‘ul.menu_body’).slideToggle(‘medium’);
    });
    $(‘ul.menu_body li a’).mouseover(function () {
    $(this).animate({ fontSize: “14px”, paddingLeft: “20px” }, 50 );
    });
    $(‘ul.menu_body li a’).mouseout(function () {
    $(this).animate({ fontSize: “12px”, paddingLeft: “10px” }, 50 );
    });
    });

    Seems to work in IE7, Firefox and Safari. If there are problems with this script please let me know.

  15. Jenn Nickerson says:

    Hi Clark,

    Got the menu working a little too well!

    Is there a way to create a vertical menu that toggles only when you click one item?

    You can see where I’m at here:
    http://chelseajewish.org

    I’m guessing either indiv. classes such as menu_body1, menu_body2 but I haven’t had much experience with jQuery and I’m not sure how to tweak this code.

    Thanks!
    Jenn

  16. Jenn Nickerson says:

    Hi Again!

    I found the answer via the Jquery forum to the “all submenus opening at once” issue.

    $(‘img.menu_head’).click(function()){
    $(this).next(‘ul.menu_body’).slideToggle(‘medium’);
    });

    Now it works.

  17. Jenn Nickerson says:

    Hi!
    One more thing. The dropdown is not working in Safari and IE (6-8) Has anyone experimented with creating conditional CSS to handle this? Has anyone else had browser compatibility issues?

    Thanks

  18. AlexQ says:

    Thanks for the tut, its very impressive.
    But i am wondering since this example works with 1 menu , is there a tut with it working with say 4 main horiz menu items floated with the ability to close the previous menu item on mouse out?

  19. Tobias H. says:

    Hey!

    I’m quite new to jQuery and certainly not the most-skilled programmer – but thanks to your fine tutorial I fully understood how to get this to work. Great stuff!

    But if you would not like this menu to just toggle but fade in and out I googled a bit and found a solution provided by Karl Swedberg, the Guru himself:

    jQuery.fn.fadeToggle = function(speed, easing, callback) {
    return this.animate({opacity: ‘toggle’}, speed, easing, callback);
    };

    $(‘img.menu_head’).click(function () {
    $(‘ul.menu_body’).fadeToggle();
    });

    This creates a nice fading effect showing or hiding the menu.

    Best regards from Germany,
    T.

  20. Tobias H. says:

    Me again …

    In your last paragraph of code there is a mistake where it shows the MOUSEOUT function. There is a ‘.’ in front of the bracket where it says:

    $(‘ul.menu_body li a’).mouseout.(function () {
    $(this).animate({ fontSize: “12px”, paddingLeft: “10px” }, 50 );
    });

    Correct this would be:
    ======================
    $(‘ul.menu_body li a’).mouseout(function () {
    $(this).animate({ fontSize: “12px”, paddingLeft: “10px” }, 50 );
    });

    Anyway, great stuff, really!
    Bstrgrds, T.

  21. Tobias H. says:

    Hehehe … me again:

    Is there a way to use a different image in the top menu bar to show an arrow pointing downwards and replacing this bit with an arrow pointing upwards, as long as the menu is collapsed? Has anyone ever thought about that? I think this would look nice and also would directly inform you visually that this menu is already collapsed (should be clear anyhow, but … you know, as a feature?)

    Bstrgrds,
    T.

  22. Jake says:

    Great drop down effect, the only concern I have is with the usability for people who have javascript disabled on their browsers.

  23. David says:

    FYI, you’ve used an image on this page that’s bigger than your main content area. It breaks your template by shoving the main content off the left side of the page on a 1024px width monitor. There is no horizontal scroll bar, so your users are screwed.

  24. timmyo says:

    @Fede re: Hi, i have one “problem”. I cant make this to go over objects, images or flash, it’s moves all the content down. It is posible TO FLOAT OVER OBJECTS?

    The most practical solution is to set your “topnav” div to a fixed height and set the overflow to “visible”. That way it won’t stretch and knock everything down and the dropdown will float over the other content.

    best

  25. 25+ jQuery plugins says:

    [...] Animated Drop Down Menu with jQuery-This great feature plugin fit a large menu into a really small initial space. For a long time people have just used a form element for standard drop downs, but with minimal effort you can create a much slicker effect using jQuery and CSS. [...]

  26. Анимированные Drop Down меню с JQuery и CSS | Создание сайтов, web программирование says:

    [...] Анимированные Drop Down Menu – Узнайте, как создать большим нетерпением выпадающее меню с гладкой эффекта с помощью JQuery и CSS. Определенно полезно и очень легко реализовать раскрывающийся навигации по сайту. [...]

  27. steve wheller says:

    Hi,

    Thanks for the great menu. I have a slight problem. In IE 7 there seems to be a 5px gap just above the menu and below the header image. This is the same on your demo page of your menu. Is there any way to fix this.

    Cheers

    Steve

  28. timo says:

    Hello

    if i use another menu same time.
    navigation dosent work. both menus opening at same time. do you have somekind of solution?

    timo

  29. Mike K says:

    I had the same trouble as many of you, where the menu would push content on the page down, instead of floating on top. I asked around and found that the solution is simple. Simply add the following lines of code to your style.css page:

    td
    {
    position:relative;
    }
    .menu_body
    {
    position:absolute;
    /*then use top left to make it in the correctly position*/
    }

    And that’s it – the menu will now float on top of content below it instead of pushing it down.

    Great menu by the way, very attractive and functional. I imagine I’ll be using this on many a website!

  30. Rakim says:

    Thank You for this. It is great. I have a problem. I can get more than one button next to each other and managed to sort out problem of the whole menu “falling”. I do however have the problem where whichever button I click the dropdown is always the same. THis is no good because you want different dropdown subheadings for each button. I of course have changed the headings in the ‘li’ in the html but for some reason I always get the same dropdown for all buttons when clicked. I wasted the whole day ont his problem.

  31. Kris says:

    Hello, there is no direct email link anywhere, so i figure i’d post it here. In your downloadable zip file, there is a spelling error in your CSS file that prevents text from shrinking back down to size upon mouserollout. You have fpmt-size:10px; instead of font-size:10px;

    Hope this helps

  32. Pierrot10 says:

    HEllo,
    That script is very good, but I ask me how I could do the same but with several menu.
    For exemple:
    NAVGATE – NAVIGATE 1 – NAVIGATE 2 – NAVIGATE 3?

    The goal is to develop only one of them when I click on it

  33. Rider-LV says:

    Hello, I have same problem as Pierrot10 – script works for all menus same time, and I dont have various names for menus.

    Please help me.

    And thanks for great menu!

  34. Antonio says:

    Worked Great, Thank you!

    If you want it to open on Hover In or Out use this:

    $(document).ready(function () {
    $(“ul.menu_body li:even”).addClass(“alt”);
    $(‘img.menu_head’).hover(function () {
    $(‘ul.menu_body’).slideToggle(‘fast’);
    },function() {
    $(‘ul.menu_body’).slideToggle(‘medium’);
    });
    $(‘ul.menu_body li a’).mouseover(function () {
    $(this).animate({ fontSize: “13px”, paddingLeft: “12px” }, 50 );
    });
    $(‘ul.menu_body li a’).mouseout(function () {
    $(this).animate({ fontSize: “12px”, paddingLeft: “10px” }, 50 );
    });
    });

    (make sure to replace single and double quotes when copy pasting from here or it wont work)

    Hope this helps

  35. natali says:

    Ótimo o post sobre jquery. O JQUERY veio para facilitar a vida dos programadores tornando mais rapido o desenvolvimento deixando as aplicacoes mais robustas e atraentes tambem. Parabens pelo post. Continue assim.

  36. Jan says:

    Great menu.
    I noticed that you have an error in your script here in the tutorial:

    $(‘ul.menu_body li a’).mouseout.(function () {

    must be

    $(‘ul.menu_body li a’).mouseout(function () {

    Have a nice day!

  37. Jquery and Web Design Tutorials says:

    [...] a menu. You can take the “click” event that happens when clicking on a menu to do lots of stuff.Animated Drop Down Menu with jQueryDrop down menus are a really convient way to fit a large menu into a really small initial space. For [...]

  38. Jeremiah says:

    Thank you so much for this, it helped me a ton!!! I really appreciate the work you did to create this tutorial. It helped me understand jquery better, and incorporate a new menu into my site!!

    Cheers,
    Jeremiah

  39. Drew says:

    I have set this up on my website I am building but I ran into a problem. When it expands it readjusts the size of the page and moves all content under it. I want it to be above all the other content as to not move it when the menu is clicked. Let me know if this makes sense. Thanks!

  40. emma vine says:

    fab tutorial, the only issue is i have more than one nested list, it wont let me apply it to them both any ideas?

  41. Abdelkader Soudani says:

    Hi, nice tutorial, i’ve been looking around for one that replaces the combo box default html input in this is one of the best.
    still one little issue though, is there any way we can select item of the list exactly like in a combo box, not just a link i mean

  42. Anthony says:

    This is awesome and I have it working fine on my site, however. I only have one issue. The drop down menu pushes down the content on the page. Is there a line of code I need to add in the CSS to make the drop down drop over the content?

  43. Ryan says:

    Hello. I’ve done everything according to this. Works great on my Google Chrome, Safari, and Internet Explorer but fails to work at all on Mozilla Firefox. Any advice?

    Thanks

  44. Ben says:

    Dude, if you’re going to provide a half ass script, at least make it work right and answer your commenters that are having problems with it not working. Your script is pushing the drop down below normal page content. The script is useless unless you can get it to work correctly.

  45. Mike says:

    For those with problem of having it push down content, throw it in a div with position: absolute; you may have to change the z-index of the content that follows to -1;

    MENU GOES HERE

  46. Mike says:

    lets try again

    <div style=”height:200px; background-color: blue;”></div>
    <div id=”menudiv” style=”background-color:#534741; height: 26px; left: 0px; right: 0px; “></div>
    <div style=”z-index: -1;position:relative;top:26px;height:200px; background-color: green;”><input type=”text”/> </div>

  47. Mikael says:

    Hi
    I have a problem.

    I am experimenting a little bit (this is the first time I have used JQuery) and figured that it would be nice open and close the menues with an mouseover and mouseout function instead of a clickfunction.

    Now the problem is as follows: I works.
    The downside is that when I move the mouse down to click on a menuitem the menu closes since I move the mouse of the image.

    Question: Is it possible to say to JQuery: Only close the menu if mouseout top, right and left and click menuitem?

    I can probaly figure out the last one myself, but the first one (mouseout top, right and left ) is more than I can handle.

    This is my code:
    $(document).ready(function () {
    $("ul.menu_body li:even").addClass("alt");
    $('img.menu_head').mouseover(function () {
    $('ul.menu_body').slideToggle('fast');
    });
    $('ul.menu_body li a').mouseover(function () {
    $(this).animate({ fontSize: "14px", paddingLeft: "20px" }, 50 );
    });
    $('ul.menu_body li a').mouseout(function () {
    $(this).animate({ fontSize: "12px", paddingLeft: "10px" }, 50 );
    });

    $('img.menu_head').mouseout(function () {
    $('ul.menu_body').slideToggle('fast');
    });
    });

    Kind Regards

  48. JAIR FORO says:

    Olá,
    Gostaria de parabenizar pelo conteúdo de altíssima qualidade, gostaria de solicitar permissão para utilização.

    Desde de Já Agradeço.

    Abraços!

  49. Anton says:

    Thanks for posting the tutorial. I think this code would be perfect if the drop down disappeared when you click anywhere on the screen rather than needing to click inside the div.

    This seems to be the standard on sites like Flickr and jsFiddle.

    Can someone post a how to on this function?

  50. responsive web design says:

    I do agree with all of the concepts you’ve presented in your post. They’re very convincing and will certainly work. Still, the posts are very brief for novices. Could you please prolong them a bit from next time? Thanks for the post.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>