Menus are a key way for visitors to go through your site and access the content. Many different types and styles of menus exist. In this tutorial, we are going to create a jQuery drop down menu that can have any number of tiers.

To begin, let’s import some of the key libraries we need.

<!-- Add jQuery From the Google AJAX Libraries -->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script> 

<!-- jQuery Color Plugin -->
<script type="text/javascript" src="jquery.color.js"></script>

This provides us with jQuery as well the color plugin so we can add extra effects. At this point, all we have is some basic HTML.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>jQuery Drop Down Menu</title> 

<!-- CSS For The Menu -->
<link rel="stylesheet" href="style.css" /> 

</head>
<body>

<!-- Add jQuery From the Google AJAX Libraries -->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script> 

<!-- jQuery Color Plugin -->
<script type="text/javascript" src="jquery.color.js"></script>

<!-- Import The jQuery Script -->
&ltscript type="text/javascript" src="jMenu.js"></script> 

</body>
</html>

Note that I have added a reference to our stylesheet, style.css, and our menu, jMenu.js. These will be created as the tutorial progresses.

It’s time to add our markup for the menu. The layout of the menu is very simple:

  • The menu will be contained as an unordered list inside a divider.
  • Each list item in the menu corresponds to one link.
  • To create a sub-menu, place a span element inside a list item. Give this element the class “toggle”, without the quotes.
  • Within this same list element, embed a nested list.
  • Add list items to this list for a sub-menu.
  • Create as many sub-menus and list items as necessary.

Here is the sample markup:

<!-- Menu Start -->
<div id="jQ-menu"> 

	<!-- Main Unordered List -->
	<ul>
		<!-- Regular List Item -->
		<li><a href="#">Lorem Ipsum</a></li> 

		<!-- List Item With A Sub-Menu - Note The toggle And sub-menu Class -->
		<li><span class="toggle">Dolor</span>
			<ul>
				<!-- A Sub-Menu In A Sub-Menu - Any Number of Nested Menus Will Work -->
				<li><span class="toggle">Sit Amet</span>
					<ul>
						<li><a href="#">Senectus</a></li>
						<li><a href="#">Aliquam</a></li>
						<li><a href="#">Vivamus</a></li>
						<li><a href="#">Magna</a></li>
						<li><a href="#">Donec</a></li>
					</ul>
				</li>
				<li><a href="#">Massa</a></li>
				<li><a href="#">Libero</a></li>
			</ul>
		</li>
		<li><span class="toggle">Eleifend</span>
			<ul>
				<li><a href="#">Pretium</a></li>
				<li><a href="#">Ornare</a></li>
				<li><a href="#">Est</a></li>
				<li><a href="#">Pellentesque</a></li>
				<li><a href="#">Habitant</a></li>
			</ul>
		</li>
		<li><span class="toggle">Morbi</span>
			<ul>
				<li><span class="toggle">Tristique</span>
					<ul>
						<li><span class="toggle">Netus</span>
							<ul>
								<li><a href="#">Fames</a></li>
							</ul>
						</li>
						<li><span class="toggle">Feugiat</span>
							<ul>
								<li><a href="#">Vtae</a></li>
								<li><a href="#">Ultricies</a></li>
							</ul>
						</li>
						<li><span class="toggle">Tincidunt</span>
							<ul>
								<li><a href="#">Tempor</a></li>
								<li><a href="#">Lacus</a></li>
							</ul>
						</li>
						<li><span class="toggle">Enim</span>
							<ul>
								<li><a href="#">Ante</a></li>
								<li><a href="#">Mauris</a></li>
							</ul>
						</li>
						<li><span class="toggle">Cras</span>
							<ul>
								<li><a href="#">Mi</a></li>
								<li><a href="#">Felis</a></li>
								<li><a href="#">Curabitur</a></li>
								<li><a href="#">Ultricies</a></li>
							</ul>
						</li>
					</ul>
				</li>
				<li><span class="toggle">Tortor</span>
					<ul>
						<li><a href="#">Quam</a></li>
						<li><a href="#">Praesent</a></li>
						<li><a href="#">Dapibus</a></li>
						<li><a href="#">Neque</a></li>
						<li><a href="#">Egestas</a></li>
						<li><a href="#">Nulla</a></li>
					</ul>
				</li>
				<li><a href="#">Fermentum</a></li>
			</ul>
		</li>
		<li><span class="toggle">Elementum</span>
			<ul>
				<li><span class="toggle">Vulputate</span>
					<ul>
						<li><a href="#">Nunc</a></li>
						<li><a href="#">Consequat</a></li>
					</ul>
				</li>
				<li><a href="#">Diam</a></li>
			</ul>
		</li>
		<li><span class="toggle">Dui</span>
			<ul>
				<li><a href="#">Placerate</a></li>
				<li><a href="#">Sem</a></li>
				<li><a href="#">Auctor</a></li>
			</ul>
		</li>
	</ul>
	<!-- End Unordered List --> 

</div>
<!-- End Menu -->

Our markup is now finished. To enhance this menu and get rid of the bullet points, we can write a CSS file, called style.css:

body {
	font-family: "Trebuchet MS", Helvetica, Sans-Serif;
	font-size: 14px;
}

#jQ-menu ul {
	list-style-type: none;
}

#jQ-menu a, #jQ-menu li {
	color: gray;
	text-decoration: none;
	padding-bottom: 3px;
}

#jQ-menu ul {
	padding-left: 15px;
}

There is not much to this CSS. Specific colors and fonts are being specified for the text. Some positioning is also added so that the menu is displayed correctly.

Our final task is to create the JavaScript that fuels this menu. This code will go into a file called jMenu.js.

$(function() {

}

All code will go in this function. jQuery uses this syntax as something similar to the window.onload function – all code will be executed when the window loads.

The first order of business in this script is to hide all sub-menus. Nothing should be expanded until the user wants to browse though it.

// hide all the sub-menus
$("span.toggle").next().hide();

Looking back at the HTML, we see that all sub-menus directly follow a span element. With this code, each element after a span element with a class of toggle will be hidden.

Now we can move on to a few effects:

// add a link nudging animation effect to each link
$("#jQ-menu a, #jQ-menu span.toggle").hover(function() {
   $(this).stop().animate( {
	fontSize:"17px",
	paddingLeft:"10px",
	color:"black"
   }, 300);
}, function() {
   $(this).stop().animate( {
	fontSize:"14px",
	paddingLeft:"0",
	color:"#808080"
   }, 300);
});

Does this code seem familiar? It is derived from the link nudging article that Patrick Lin posted, which you can read here. The explanation is provided in his article.

Two problems appear at this point. The span elements have a normal text cursor when the user hovers over one of them. This gives the feeling that they aren’t links to open up a sub-menu.

The next problem is that the user is unable to tell which list-items are links and which are links to sub-menus. There is no difference.

To remedy these problems, we can add two lines of JavaScript:

// set the cursor of the toggling span elements
$("span.toggle").css("cursor", "pointer");

// prepend a plus sign to signify that the sub-menus aren't expanded
$("span.toggle").prepend("+ ");

The first line changes the cursor of all span elements to a pointer. The next one prepends a + sign to span elements, which lets the user know that he or she is expanding a sub-menu.

For the finale, we have to show and hide the sub-menus when the corresponding span element is clicked. The + signs should be switched to – signs when the menus are expanded.

// add a click function that toggles the sub-menu when the corresponding
// span element is clicked
$("span.toggle").click(function() {
	$(this).next().toggle(1000);

	// switch the plus to a minus sign or vice-versa
	var v = $(this).html().substring( 0, 1 );
	if ( v == "+" )
		$(this).html( "-" + $(this).html().substring( 1 ) );
	else if ( v == "-" )
		$(this).html( "+" + $(this).html().substring( 1 ) );
});

According to the above code, when a span element is clicked, the next HTML element (which is the sub-menu) gets toggled. The + sign gets switched to a – sign or vice-versa when the sub-menu gets expanded or contracted.

The toggle(1000) statement controls the time it takes to toggle the element. You can customize the number passed to this function to change the time. Note that the number passed is in milliseconds. In this case, it takes 1000 milliseconds, or 1 second, for the menu to expand/contract.

Here is the final code:

Our HTML File:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>jQuery Drop Down Menu</title> 

<!-- CSS For The Menu -->
<link rel="stylesheet" href="css/style.css" /> 

</head>
<body> 

<!-- Menu Start -->
<div id="jQ-menu"> 

	<!-- Main Unordered List -->
	<ul>
		<!-- Regular List Item -->
		<li><a href="#">Lorem Ipsum</a></li> 

		<!-- List Item With A Sub-Menu - Note The toggle And sub-menu Class -->
		<li><span class="toggle">Dolor</span>
			<ul>
				<!-- A Sub-Menu In A Sub-Menu - Any Number of Nested Menus Will Work -->
				<li><span class="toggle">Sit Amet</span>
					<ul>
						<li><a href="#">Senectus</a></li>
						<li><a href="#">Aliquam</a></li>
						<li><a href="#">Vivamus</a></li>
						<li><a href="#">Magna</a></li>
						<li><a href="#">Donec</a></li>
					</ul>
				</li>
				<li><a href="#">Massa</a></li>
				<li><a href="#">Libero</a></li>
			</ul>
		</li>
		<li><span class="toggle">Eleifend</span>
			<ul>
				<li><a href="#">Pretium</a></li>
				<li><a href="#">Ornare</a></li>
				<li><a href="#">Est</a></li>
				<li><a href="#">Pellentesque</a></li>
				<li><a href="#">Habitant</a></li>
			</ul>
		</li>
		<li><span class="toggle">Morbi</span>
			<ul>
				<li><span class="toggle">Tristique</span>
					<ul>
						<li><span class="toggle">Netus</span>
							<ul>
								<li><a href="#">Fames</a></li>
							</ul>
						</li>
						<li><span class="toggle">Feugiat</span>
							<ul>
								<li><a href="#">Vtae</a></li>
								<li><a href="#">Ultricies</a></li>
							</ul>
						</li>
						<li><span class="toggle">Tincidunt</span>
							<ul>
								<li><a href="#">Tempor</a></li>
								<li><a href="#">Lacus</a></li>
							</ul>
						</li>
						<li><span class="toggle">Enim</span>
							<ul>
								<li><a href="#">Ante</a></li>
								<li><a href="#">Mauris</a></li>
							</ul>
						</li>
						<li><span class="toggle">Cras</span>
							<ul>
								<li><a href="#">Mi</a></li>
								<li><a href="#">Felis</a></li>
								<li><a href="#">Curabitur</a></li>
								<li><a href="#">Ultricies</a></li>
							</ul>
						</li>
					</ul>
				</li>
				<li><span class="toggle">Tortor</span>
					<ul>
						<li><a href="#">Quam</a></li>
						<li><a href="#">Praesent</a></li>
						<li><a href="#">Dapibus</a></li>
						<li><a href="#">Neque</a></li>
						<li><a href="#">Egestas</a></li>
						<li><a href="#">Nulla</a></li>
					</ul>
				</li>
				<li><a href="#">Fermentum</a></li>
			</ul>
		</li>
		<li><span class="toggle">Elementum</span>
			<ul>
				<li><span class="toggle">Vulputate</span>
					<ul>
						<li><a href="#">Nunc</a></li>
						<li><a href="#">Consequat</a></li>
					</ul>
				</li>
				<li><a href="#">Diam</a></li>
			</ul>
		</li>
		<li><span class="toggle">Dui</span>
			<ul>
				<li><a href="#">Placerate</a></li>
				<li><a href="#">Sem</a></li>
				<li><a href="#">Auctor</a></li>
			</ul>
		</li>
	</ul>
	<!-- End Unordered List --> 

</div>
<!-- End Menu --> 

<!-- Add jQuery From the Google AJAX Libraries -->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script> 

<!-- jQuery Color Plugin -->
<script type="text/javascript" src="js/jquery.color.js"></script> 

<!-- Import The jQuery Script -->
<script type="text/javascript" src="js/jMenu.js"></script> 

</body>
</html>

Our CSS File:

body {
	font-family: "Trebuchet MS", Helvetica, Sans-Serif;
	font-size: 14px;
}

#jQ-menu ul {
	list-style-type: none;
}

#jQ-menu a, #jQ-menu li {
	color: gray;
	text-decoration: none;
	padding-bottom: 3px;
}

#jQ-menu ul {
	padding-left: 15px;
}

Our JavaScript File:

$(function() {
	// hide all the sub-menus
	$("span.toggle").next().hide();

	// add a link nudging animation effect to each link
    $("#jQ-menu a, #jQ-menu span.toggle").hover(function() {
        $(this).stop().animate( {
			fontSize:"17px",
			paddingLeft:"10px",
			color:"black"
        }, 300);
    }, function() {
        $(this).stop().animate( {
			fontSize:"14px",
			paddingLeft:"0",
			color:"#808080"
        }, 300);
    });

	// set the cursor of the toggling span elements
	$("span.toggle").css("cursor", "pointer");

	// prepend a plus sign to signify that the sub-menus aren't expanded
	$("span.toggle").prepend("+ ");

	// add a click function that toggles the sub-menu when the corresponding
	// span element is clicked
	$("span.toggle").click(function() {
		$(this).next().toggle(1000);

		// switch the plus to a minus sign or vice-versa
		var v = $(this).html().substring( 0, 1 );
		if ( v == "+" )
			$(this).html( "-" + $(this).html().substring( 1 ) );
		else if ( v == "-" )
			$(this).html( "+" + $(this).html().substring( 1 ) );
	});
});

And that’s it!

Take a look at our jQuery accordion menu post for a nice alternative!

You may view a working demo and download the files.

Leave a Reply

JQuery Drop Down Menu