http://clarklab.com/posts/animated-drop-down-menu-with-jquery/
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:
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:
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:
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:
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:
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.