thatryan.com

  • home
  • about
  • blog
  • portfolio
  • contact

Creating A Simple jQuery Drop Down Menu

Mar. 8, 2010 Tutorials / 8 Comments

What’s on the menu?

Yeah, I really just typed that. But, it is a very valid question if you think of it right? I mean, at first glance you sometimes can’t tell just what is on the menu because of the wonder that are drop downs. A space saver and organization tool that many menus employ to help us find just what is on the menu in a friendly timely fashion. The question then becomes, how does one emulate this behavior? When I first began working in web development I remember searching like crazy to find out how to make a drop down navigation menu, and so I am now writing my own for, hopefully, others to search like crazy for!

So this tutorial is how to create a simple drop down menu using jQuery. Alright let’s drop down in and get going.



From Here To There

  • HTML To Start
  • Making It Pretty
  • Up’s and Down’s
  • Comments!

First here is a demo of what we will be making, so give it a look then hurry back for fun!

[one_third][info_box]Demo Here![/info_box][/one_third]
[divider]

HTML To Start

[divider_top]
Back? Ok cool. Now start by making a new HTML file, I was very creative and named mine menu.html and drop in a skeletal markup. Then go ahead and include the stuff we will be using but have not made yet ;) In the

section drop in the following,

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js" type="text/javascript"><!--mce:0--></script>
<script src="simpleMenu.js" type="text/javascript"><!--mce:1--></script>

The first is obviously just a stylesheet we have yet to build, and then we include jQuery from the uber-quick Google CDN. Next we import the script for this rad menu that we will make shortly.

Now the first thing we are going to do is build a menu, just as we would any normal menu so drop this into your body,

<div id="wrapper">

<h1>Simple jQuery Drop-Down Menu</h1>

<ul class="main_nav">

	<li><a>Menu 1</a>

<ul class="sub_nav">

	<li><a href="#">Link 1</a></li>

	<li><a href="#">Link 2</a></li>

	<li><a href="#">Link 3</a></li>

	<li><a href="#">Link 4</a></li>

	<li><a href="#">Link 5</a></li>

</ul>
</li>

	<li><a>Menu 2</a></li>

	<li><a>Menu 3</a>

<ul class="sub_nav">

	<li><a href="#">Link 1</a></li>

	<li><a href="#">Link 2</a></li>

	<li><a href="#">Link 3</a></li>

	<li><a href="#">Link 4</a></li>

</ul>
</li>

	<li><a>Menu 4</a></li>

</ul>
</div>

I don’t really need to explain this I know, but just in case, what we do here is layout the markup for a main navigation list that includes regular list elements for links. However, on the menu items that we wish to have a drop down components, instead of closing the initial list element right away, we insert a second unordered list component and give it a class of “sub_nav” to grab later on.

If you check this out in the browser, it should look something like this,

Unstyled Menu

Unstyled Menu


Making It Pretty

[divider_top]
Alright moving along now we are going to make a new file and name it style.css. First part I am going to add is just rough style for the page so it is not all so boring to look at,

body {
font-family:Helvetica Neue,Arial,Helvetica, sans-serif;
font-size: 16px;
background: #666;
background:rgba(9,9,9,0.6);
}
#wrapper {
width: 600px;
height: 400px;
margin: 10px auto;
padding-top: 20px;
background-color: #fff;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
box-shadow: 1px 1px 1px #333;
-moz-box-shadow: 1px 1px 1px #333;
-webkit-box-shadow: 1px 1px 1px #333;
}
#wrapper h1 {
text-align: center;
font-family: Palatino,Palatino Linotype,Hoefler Text,Times,Times New Roman,serif;
font-size: 32px;
color: #333;
text-shadow: #777 0px 0px 1px;
}
ul,li {
margin: 0;
padding: 0;
list-style: none;
}

Like I said, nothing too special about this, it is just to liven up the page itself. Bear in mind that I am using a few CSS3 attributes in here, so if you are not on a (cool) browser it will not look the same. ;)

Next, I am going to apply styling for the main navigation; that is, the top level menu,

ul.main_nav {
margin: 0 auto;
width: 500px;
}
ul.main_nav li {
background-color: #3299BB;
border-right: 1px solid #BCBCBC;
float: left;
position: relative;
text-align: center;
}
ul.main_nav > li:first-child {
-moz-border-radius-topleft: 10px;
-webkit-border-top-left-radius: 10px;
}
ul.main_nav > li:last-child {
border: none;
-moz-border-radius-topright: 10px;
-webkit-border-top-right-radius: 10px;
}
ul.main_nav li a {
color: #FFFFFF;
width: 100px;
padding: 10px;
text-decoration: none;
display: block;
}
ul.main_nav li a:hover {
color: #424242;
}

Here we apply some standard styling but there are a few pieces that are must do’s. First We give the main menu li elements some color and a right side border to separate them a bit. The most important part to notice here is that we give the list elements a position of relative. This is to ensure that we can absolutely position their ul list that

Now in order to accomplish the pretty, albeit unnecessary, round edges on the top left and right of the menu, we use the mozilla and webkit prefixes to round the radii. The targets ul.main_nav > li:first-child and :last-child, target the first item in the unordered list and the last item, respectively. The usage of the “>” less-than attribute here is needed because it tells the browser to only target the immediate decedents of the main_nav ul. If we remove the less-than attribute then that radius property would be applied to all first and last list elements, this includes the sub_nav menus and that would look silly.

Next we add styling to the links in the list elements, by adding them to the “a” attribute instead of the “li” attribute, we allow the inner-most element to dictate the width for the list and set the links to a display value of block so that the entire list is “clickable.”

Carrying on now we will do the same type of thing to our nested menu, the sub_nav menu, so add this chunk of style into your CSS file,

ul.main_nav li ul.sub_nav {
position: absolute;
left: 0px;
top: 100%;
display: none;		/*initially hide sub menu */
}
ul.main_nav li:hover > ul {
display: block;		/*show on hover,javascript disabled */
}
ul.main_nav li ul.sub_nav li {
background-color: #424242;
border-right: none;
border-top: 1px solid #BCBCBC;
text-align: left;
}
ul.main_nav li ul.sub_nav li:first-child {
border: none;
}
ul.main_nav li ul.sub_nav li a:hover {
color: #FF9900;
}
ul.main_nav li ul.sub_nav li:last-child {
-moz-border-radius-bottomright: 10px;
-moz-border-radius-bottomleft :10px;
-webkit-border-bottom-right-radius: 10px;
-webkit-border-bottom-left-radius: 10px;
}

So in this sub menu section there are a few more important styles we need to address. First, we give the sub_nav class the absolute position that we need in order for it to appear where we want it to. Setting the left to 0 and the top to 100% position the sub menu list exactly at the bottom of its parent. Also important, set the display property to none initially. This is because we do not want the menu to be showing right away now do we? Nope! This will also allow our menu to degrade if, for some reason, the user has JavaScript turned off.

The next style takes care of showing the list for those with JavaScript off, and pay attention to how it is called on. Once again we use the less than “>” operator, to be sure that when we hover over a list item, we only want to show that list items sub menu, we give it a display of block so that the sub menu appears.

The remaining styles are mostly just choices. I set the text to align left rather than center for all the sub menu items. Also I add some more styling using the first and last children specifiers, just to give the bottom of the menu a little curvy fun. :)

Little Style

Little Style

Viewing what we have now in a browser should reveal a pretty little menu, that even works! Hover over the list and the sub menus should show up nicely, but we can make it a little more smooth. So now to add some JavaScript.


Up’s and Down’s

[divider_top]
The JavaScript needed to make this awesome is surprisingly simple, so grab this and drop it in a new file name simpleMenu.js and then I will walk through it.

$(document).ready(function () {

	$('ul.sub_nav').hide();

    $('ul.main_nav li').hover(function () {

			$(this).find('> ul').stop(true, true).slideDown('slow');

 		}, function() {

 			$(this).find('> ul').stop(true, true).slideUp('slow');

		});

});

Short right? Cool. Now what we do is first begin a new function that will run when the DOM is ready. Inside here the first thing I do is make sure to hide an sub_nav ul’s that may be visible. This is mainly to be sure that our menu is not showing already and that we take control of it via JavaScript because our CSS also has the ability to show it. Remember we allowed that to work in case the user has scripts disabled.

We then start a new function first by finding all list elements inside and unordered list with a class name of “main_nav” and we listen for when it is hovered over. When that occurs we jump into the function and use the jQuery object, $(this), (which in this case is shorthand for writing out ‘ul.main_nav li’) and locate its immediate ul child, if it has one. If it does not, then this will not execute. Once found we tell it to slide down to reveal itself, and I gave it the speed of “slow” because, well, I liked it.

Sliding Around

Sliding Around

The hover function allows a callback function which works as a “mouseout” type of action, so once the hovering is no longer occurring, we tell that same child list to slide back up and hide.

Important note here, the chained function “stop()” is a tip I picked up from the awesome Jeffrey Way over at net.tutsplus.com. Without chaining that in there, the menus would still work, only if you mouse over them repeatedly back and forth then wait, the animations would continue until it catches up. So, you could be done looking at the nav, but the menu would continue to go up and down until the cycle of animations is complete. This function tells jQuery to stop the animations after the current one has completed. Thanks Jeff!

Ok people, that is about it. Save this file and jump into your browser. Give it a refresh and watch your smooth menu slide to your hearts content. Feel free to experiment with speeds and even animations if you like. You can change the slideUp and slideDown functions to fades or whatever catches your fancy. :)


Talk Back!

[divider_top]
I hope this was helpful to you, and you can download my source code below. Please leave a comment, question, feedback, tweet, or a cookie! Thanks for stopping by!

[one_third][info_box]Demo Link[/info_box][/one_third]

[one_third][download_box]Source[/download_box][/one_third]

8 Comments »

  1. Eric Mar 8 2010 @ 1:17 pm

    As always Ryan you continue to impress me. Nice tut ill be using this later!

  2. Christina Mar 8 2010 @ 1:28 pm

    Are you sure i can’t just use failweaver? :) jk. This is great Ryan! Always great instruction from you, so keep doing what you love and teaching others. I will definitely always refer back to your tutorials when I get more into using jquery.

    The site is looking great by the way.

  3. thatryan Mar 8 2010 @ 1:59 pm

    Hey guys you are awesome! Thank you so much for reading and enjoying. This truly is the best community ever, how can one NOT enjoy this! lol

  4. Brett Mar 9 2010 @ 3:24 pm

    This is awesome. I’m going to try it. Thank You! Oh and that post header looks awesome, great job.

  5. Create a dropdown menu using jQuery! Mar 9 2010 @ 4:05 pm

    [...] See the complete tutorial here! Share and Enjoy: [...]

  6. Andrea Mar 9 2010 @ 4:40 pm

    Awesome stuff Ryan, you’re on a roll dude!

  7. thatryan Mar 10 2010 @ 11:20 am

    Hey guys thanks so much! I appreciate all your support, makes all this even more fun. :)

  8. ztapoz Jun 4 2010 @ 8:12 pm

    I’m from VietNam. Thank you very much. I’d like tut.

Leave a comment

Cancel Reply

recent comments

  • marc-andremenard on Build a jQuery Tabbed Widget for WordPress
  • Bob on Ajaxing a jQuery Contact Form-Part Two
  • Hello on Ajaxing a jQuery Contact Form-Part Two
  • Hello on Ajaxing a jQuery Contact Form-Part Two
  • Ryan Vars on How To Build a Custom Theme For Concrete5 From Scratch

Categories

  • Blog
  • Portfolio
  • Reviews
  • Tutorials

Archives

  • June 2010
  • April 2010
  • March 2010
  • February 2010
  • January 2010
  • December 2009

Flickr

Copyright © 2010. All Rights Reserved.thatryan.com | Ryan Olson