Drop-Down Menus

When a webpage has more links than the designer wants to make visible, a common approach is to use a drop-down menu. You'll see an example at the top of this page, but I'm sure you're already familiar with them. While there are many ways to create drop-down menus, we will just discuss one of them.

Unlike many drop-down menus, however, we are going to require the user to click on the menu in order to reveal the hidden links. This is because the action of hovering over a menu item, which works fine with computer mice, doesn't work so well with touch-screen devices. By using only the click event, our approach will work for both mice and fingertips.

Drop-down in Action

Here's a link to a page with the final drop-down menu that we will build. It is fully functional, mobile-friendly, and the CSS is comprehensible.

Use view source on that page to see exactly how we did it.

Concepts

Drop-down Development

Let's start with a set of menus without any CSS or JS at all:

Now, let's add the CSS to make them look pretty. You're welcome to look at the CSS, but we basically just use simple stuff like color, margin, padding, width, text-decoration:none, list-style-type:none, text-align and border. The more complex CSS is:

For purposes of exposition, we omitted the display:none on the sub-menus and made the parents wider so that all the sub-menus could be displayed without overlapping.

Now, we'll add a simple click-handler that just toggles the sub-menu. We'll add it by code like this:

function toggleSubmenu_v1() {
    $(this).find("ul").toggle();
}

$(".has_submenu").click(toggleSubmenu_v1);

You could use this kind of interface, but it's not what people expect, because it's possible to open several menus at once. (Try it!) Usually, if you click on a heading, say "News", to open it, and then you on another heading, say "CS110", you expect the "News" submenu to close. We'll achieve this by adding a click handler to the document that closes all the submenus. Like this:

function closeAll() {
    $(".has_submenu ul").hide();
}

$(document).click(closeAll);

However, that has a hidden trap, which is that if we click on "News," that also counts as a click on the document. That is, the click event bubbles up the document from child to parent until it reaches the very top (which is the document selector we saw above). What we want to do is stop the bubbling or propagation of this event.

To do that, we add an argument to the click handler for top-level menu items. The argument is typically called something like event or evt. That argument will be given a value by the browser when it invokes the click handler. The value is an object that includes a lot of information about the event. The event object also has a method called stopPropagation, which is exactly the tool we need. So here's our new code:

function toggleSubmenu_v2(event) {
    event.stopPropagation();
    $(this).find("ul").toggle();
}

$(".has_submenu").click(toggleSubmenu_v2);

Here's the new menu:

Credit

We were inspired by this which we based on this wonderfully written tutorial by Iggy on a how to create a pure CSS Drop-down Menu. Unfortunately, that tutorial uses :hover, which is great of desktop applications where a mouse can hover over a menu item to reveal a submenu, but that doesn't work with touch-screen applications, as most mobile devices are. Since we want to write pages that are usable with touch-screens, we ultimately had to abandon Iggy's approach. Still, hat's off to it.