Make a Mega Drop-Down Menu with jQuery

Share this article

This article was written in 2009 and remains one of our most popular posts. If you’re keen to learn more about jQuery, you may find this recent article on the jQuery plugin registry of great interest.
Mega drop-down menus are cropping up everywhere, and now that usability guru, Jakob Nielsen thinks they’re quite good, you can expect to see even more of these very soon. Here’s what he had to say about this trend:
Given that regular drop-down menus are rife with usability problems, it takes a lot for me to recommend a new form of drop-down. But, as our testing videos show, mega drop-downs overcome the downsides of regular drop-downs. Thus, I can recommend one while warning against the other.
Of course, Nielsen’s article includes some solid advice on the most usable way to implement these. Here’s what he recommends, in a nutshell:
  • The best mega drop-down menus contain simple, logical groups of information — so they’re easy to scan and navigate.
  • Keep them simple — avoid using complex GUI items or other fiddly interactive elements.
  • A mega drop-down menu should only appear after the user has been hovering for 0.5 seconds. If the menus are set to appear instantly, and a user is casually rolling their mouse over the menu, they’ll see a bunch of menus flickering about — and that’s a nuisance.
  • If the user mouses away from the menu item or the mega drop-down, the drop-down should remain for 0.5 seconds — just in case the user accidentally rolled their mouse out of the box.
So how would we go about implementing these? While it’d be great to do all of this in pure HTML and CSS, it’s impossible at the moment to get those nice half-second delays — and of course there’s a pesky problem with Internet Explorer 6, which only supports :hover on anchor elements. Instead, I’ve whipped up a solution using jQuery and a very nifty plugin called hoverIntent.

The Design

Let’s imagine we have a client, Mega Shop. Their designer has sent us a mockup that includes some mega drop-down menus. You can see the relevant part of that mockup below (view a full sized version here). A mockup of the intended design, showing a mega dropdown

The Markup

First: the markup. I started out with a fairly simple menu based on an unordered list. The markup looks like this:
<ul id="menu">
  <li><a href="#">Home</a></li>
  <li><a href="#">Stuff for him</a></li>
  <li><a href="#">Stuff for her</a></li>
  <li><a href="#">Stuff for kids</a></li>
  <li><a href="#">Stuff for pets</a></li>
</ul>
I’ll add a div after each of the drop-down links — these will contain the contents of the menu. Also, I’d like to have a way to indicate that there’s a drop-down choice on those items, so I’ll also add a class, .mega, to those list items. Finally, I want to make sure that this menu makes sense when viewed without styles, and since each category will act as a kind of heading, I’ll add some heading markup to the items. Here’s a single list item:
<li class="mega">
  <h2>
    <a href="#">Stuff for him</a>
  </h2>
  <div>
      <!-- Contents here -->
  </div>
</li>
Next, let’s add some content to those divs. Here’s one:
<li class="mega">
  <h2>
    <a href="#">Stuff for him</a>
  </h2>
  <div>
      <h3>
        Menswear
      </h3>
      <p>
        <a href="#">Shirts</a>, 
        <a href="#">T-shirts</a>, 
        <a href="#">Accessories</a>,
        <a href="#">More...</a>
      </p>
      <h3>
        Gifts
      </h3>
      <p>
        <a href="#">Sporting goods</a>, 
        <a href="#">Gadgets</a>, 
        <a href="#">More...</a>
      </p>
      <h3>
        Clearance!
      </h3>
      <p>
        40% off all photo accessories 
        this weekend only. 
        <a href="#">Don't miss out!</a>
      </p>
    <a href="#" class="more">
      More stuff for him...</a>
  </div>
</li>
Of course, I’ll need to add the markup to represent the site’s heading. Unfortunately, we’re out of time to discuss that in detail, but you can see what I’ve done in our first example, unstyled.html.

Style

Next, I’ll lay on some style. For now, we’ll just concentrate on the most pertinent parts of styling the list elements and the drop-downs. However, if you’re curious to see the entire stylesheet, you can view it in full in our second example, styles.css
. Each mega list item is set to display inline to achieve that nice horizontal bar. We’d like the drop-down menus to overlay the page, immediately under the list item; to achieve this we’ll use position: relative on each mega list item, and later we’ll use position: absolute on the divs:
ul#menu li {
  display: inline;
  position: relative;
}
Each div is styled up to resemble the mockup we received from the designer. I’ve used position: absolute here to align them flush left with each list item, and place them just underneath. I’ve also used display: none as a catch-all for all divs that are descendants of that menu, which will help to hide the one that’s sitting underneath the homepage link:
ul#menu div {
  display: none;
}

ul#menu li.mega div {
  width: 18em;
  position: absolute;
  top: 1.6em;
  left: 0em;
}
I’ll add another class for those list items, .hovering, and make its child div elements visible with display: block. Later, using JavaScript, I’ll add the .hovering class to the list item when the mouse hovers over it, and remove the class when the mouse leaves the area:
ul#menu li.hovering div {
  display: block;
}

Script

Now, let’s add the JavaScript. I’ve chosen to use jQuery for this example; of course, you’re welcome to write your own scripts or use a different framework. You might be thinking it’s a bit of overkill to use all the overhead of a huge library for one little menu. This is just one part of our hypothetical ecommerce site, however, and I’d almost certainly be planning to use jQuery for other parts of the interface as well. First, of course, I’ll include the jQuery library. Next, I’ll also include a very nifty plugin called hoverIntent. jQuery has its own hover event, but it fires as soon as the mouse touches the target area. Instead, we want to implement the delayed effect Jakob Nielsen recommended: that is, we’d like to wait for the user to stop moving their mouse. The hoverIntent plugin provides for this by taking the mouse movement speed into account. First, we’ll need to write a couple of functions to add and remove the .hovering class — that’s the class which switches on the display of the mega item:
function addMega(){
  $(this).addClass("hovering");
  }

function removeMega(){
  $(this).removeClass("hovering");
  }
And then, we’ll use the hoverIntent function to fire off those functions when we hover over an item or leave it. First, we need to set some configuration variables:
var megaConfig = {    
     interval: 500,
     sensitivity: 4,
The interval parameter specifies a number of milliseconds (that is, thousandths of seconds) which hoverIntent uses to check on the mouse’s movement. The sensitivity parameter specifies the number of pixels a mouse should have traveled during the interval parameter in order to be considered moving. If the mouse has moved less than that, the mouse is considered to be hovering.
     over: addMega,
The over parameter specifies a function that will be called when the mouse has stopped.
     timeout: 500,
     out: removeMega
     };
The timeout parameter specifies how long we’d like to wait in milliseconds before performing the mouse out function. The out parameter specifies what to do once that delay has passed — so in this example, the hideMega function will be called after 500 milliseconds. Finally, we’ll attach the hoverIntent function to the .mega list items, telling it to start looking for hovers and mouseouts, using the configuration we set up:
$("li.mega").hoverIntent(megaConfig)
And that’s about it!

Testing Time

Time to test out our menu! You can see the completed demo with the markup, style, and script in our final example, completed.html.

What Now?

There’s a lot more that can be added here — for example, a drop-down menu can have some significant accessibility problems, so it’d be good to find a way to also add keyboard actions to this menu. It’d also be nice to add some more interesting design elements to these menus, like icons, shadows, or column arrangements. For now, though, we have quite a solid start! If you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, like jQuery Fundamentals. Comments on this article are closed. Have a question about jQuery? Why not ask it on our forums?

Frequently Asked Questions about Mega Drop-Down Menu with jQuery

How can I add submenus to my mega drop-down menu?

Adding submenus to your mega drop-down menu can be done by nesting another unordered list within a list item. Each list item in the nested unordered list will represent a submenu item. You can style these submenu items using CSS to achieve the desired look and feel. Remember to add the necessary jQuery code to handle the hover or click events for these submenu items.

Can I use images in my mega drop-down menu?

Yes, you can use images in your mega drop-down menu. You can add an image tag within a list item and use CSS to style it. You can also use background images for your menu items by setting the background-image property in your CSS.

How can I make my mega drop-down menu responsive?

Making your mega drop-down menu responsive involves using CSS media queries to adjust the layout and design of the menu based on the screen size. You can also use jQuery to dynamically adjust the menu based on the screen size.

How can I add a search box to my mega drop-down menu?

You can add a search box to your mega drop-down menu by adding an input element of type “search” within a list item. You can then use jQuery to handle the search functionality.

Can I use animations in my mega drop-down menu?

Yes, you can use animations in your mega drop-down menu. jQuery provides several methods for creating animations, such as fadeIn(), fadeOut(), slideDown(), and slideUp(). You can use these methods to animate the showing and hiding of your menu.

How can I add icons to my menu items?

You can add icons to your menu items by using an icon font like Font Awesome or by using images. If you’re using an icon font, you can add the icon class to a span element within your list item.

How can I make my mega drop-down menu accessible?

Making your mega drop-down menu accessible involves adding appropriate ARIA roles and attributes, providing keyboard navigation, and ensuring that your menu is usable without JavaScript.

Can I use CSS transitions for animations instead of jQuery?

Yes, you can use CSS transitions for animations instead of jQuery. CSS transitions provide a way to control animation speed when changing CSS properties.

How can I add a scrollbar to my mega drop-down menu?

You can add a scrollbar to your mega drop-down menu by setting the overflow property to “auto” in your CSS. This will add a scrollbar when the content of your menu exceeds its height or width.

Can I use a mega drop-down menu with a single page application (SPA)?

Yes, you can use a mega drop-down menu with a single page application (SPA). You would need to update the menu based on the current state of the application, which can be done using jQuery.

Raena Jackson ArmitageRaena Jackson Armitage
View Author

Raena Jackson Armitage is an Australian web developer with a background in content management, public speaking, and training. When she is not thinking about the Web, she loves knitting, gaming, all-day breakfasts, and cycling.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week