Touch-friendly drop-down menus

Drop-down menus are a popular form of website navigation, but many implementations suffer from serious usability problems: accidental activation (when the mouse briefly passes over the menu), accidental deactivation (when the mouse briefly moves off the menu whilst moving between items), deeper sub-menus appearing off the edge of the screen, dependency on JavaScript, a lack of support for right-to-left languages, and a lack of touch support. Dropdown is a JavaScript object and associated stylesheet that solves these problems. The examples below show the various types of drop-down menus that can be created.

(In order to reduce the size of this page, these examples use JavaScript to generate the 390 items in the sub-menus. In normal usage all items would be present in the HTML, and the Dropdown.css stylesheet would enable the drop-down menu to function even with JavaScript disabled.)

Download Dropdown

Download one of the files below and either incorporate it into your code or serve it as a separate file.

File Size Description
Dropdown.js 2,935 bytes Minified version
Dropdown.src.js 8,220 bytes Full version, with comments

Dropdown.js does not apply any styling to the drop-down menus. Download one of the files below and either incorporate it into your stylesheet or serve it as a separate file.

File Size Description
Dropdown.css 1,085 bytes Stylesheet, universal
Dropdown.ltr.css 869 bytes Stylesheet, left-to-right languages only
Dropdown.rtl.css 873 bytes Stylesheet, right-to-left languages only

Creating drop-down menus

Drop-down menus are represented using semantic HTML as sets of nested lists. For example, a drop-down menu with two sub-menus each containing two items would use HTML of the following form:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<ul class="dropdown">
  <li>
    <a href="">Page 1</a>
    <ul>
      <li>
        <a href="">Sub-page 1.1</a>
      </li>
      <li>
        <a href="">Sub-page 1.2</a>
      </li>
    </ul>
  </li><li>
    <a href="">Page 2</a>
    <ul>
      <li>
        <a href="">Sub-page 2.1</a>
      </li>
      <li>
        <a href="">Sub-page 2.2</a>
      </li>
    </ul>
  </li>
</ul>

The dropdown class on line 1 is used to style the menu and to enable the JavaScript to automatically identify all menus on the page. By default the menu is styled as a horizontal menu; to style the menu as a vertical menu set the class to dropdown dropdownVertical. If any ancestor element has its dir attribute set to rtl (or if the stylesheet for right-to-left languages is used) then the menu will run right-to-left; for pages written entirely in a right-to-left script the dir attribute should usually be set on either the html element or the body element.

Horizontal menus use inline-block styling. To avoid additional space appearing between the top-level items, the space should be removed from the HTML. This technique can be seen on line 12 of the code above, where there is no space between the li elements.

Additional classes can be applied to any element within the menu. The default styling assumes the individual items will be contained within a or span elements, but items may use any element except ul; the last example at the top of this page demonstrates complex menu items.

Applying the JavaScript

The drop-down menus function even without JavaScript, but the JavaScript greatly improves their usability. To activate the JavaScript, call the initialise function on page load using code such as the following (which uses the runOnLoad function):

1
2
// initialise the drop-down menus
runOnLoad(Dropdown.initialise);

This function will also apply the JavaScript to any existing ul element with the class dropdown.

If a drop-down menu is dynamically created after initialising the JavaScript, the ID of the element or the DOM node corresponding to it should be passed to the applyTo function:

1
2
3
4
5
// apply the JavaScript to a menu by passing an ID
Dropdown.applyTo('menu1');

// apply the JavaScript to a menu by passing a DOM node
Dropdown.applyTo(document.getElementById('menu2'));

Styling drop-down menus

Dropdown.css applies minimal styling to drop-down menus. The following style rules, which assume the individual items will be contained within a or span elements, can be used as a starting point for more advanced formatting:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
/* set the background colour */
.dropdown,
.dropdown ul{
  background : rgb(128,192,64);
}

/* pad items, set their text colour, and fade their background colour */
.dropdown a,
.dropdown span{
  padding    : 0.25em 0.5em;
  color      : white;
  transition : background 0.2s;
}

/* set the background colour of active items */
.dropdown li:hover > a,
.dropdown li:hover > span,
.dropdown li.dropdownOpen > a,
.dropdown li.dropdownOpen > span{
  background : rgb(160,208,112);
}

To centre a drop-down menu, use the text-align property:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
/* centre the menu */
.dropdown{
  text-align : center;
}

/* align the menu content */
.dropdown > li{
  text-align : left;
}
[dir=rtl] .dropdown > li{
  text-align : right;
}

Where now?

Found this useful? Share it:

Recommended reading:

Professional JavaScript for Web Developers by Nicholas C. Zakas

Also in JavaScript: