Navigational pulldown menus in HTML

Can you construct a pulldown (dropdown) menu in HTML so that the menu entries correspond to Web page addresses? There are various methods, and some of them can be technically reliable. This document also explains better alternatives to navigational pulldown menus.

Content

Preface: why it's more complicated than you'd think

A pulldown menu might look like the following:

That has been written in HTML using the SELECT element. (That element has good uses in conjunction with normal use of forms in HTML for submission of data to some processing. We are discussing a different use of it here.)

You may have seen such constructs on Web pages, and you might expect that first selecting an option from the pulldown list, then clicking on the "Go!" button would lead you to a page on the topic appearing as option name. Don't bother. It doesn't work. HTML authors often try to build "navigational menus" based on SELECT, and it can be done, but not within HTML only, and not without getting things right.

The code for the simple form used above is the following:

<FORM ACTION="notworking.html">
<DIV>
<SELECT>
<OPTION SELECTED>Main page on HTML forms
<OPTION>Choices in HTML forms
<OPTION>Tables and forms
<OPTION>Form submission methods (GET and POST)
</SELECT>
<INPUT TYPE="SUBMIT" VALUE="Go!">
</DIV>
</FORM>

That's a simplified version of what authors often try, and it cannot work. It always takes the user to the page specified in the ACTION attribute. There is nothing you can do in HTML alone about it. People sometimes try to make things work by writing some addresses (URLs) into OPTION elements (say, OPTION NAME="URL" VALUE="index.html"), but there is no reason to think that it would help. Instead of trying to make computers do what you mean, you need to check what they can be expected to do when you give them specific data or instructions.

Whatever you put into an OPTION element will only affect the data that is sent along with the submitted form. Data per se doesn't do anything.

Various methods

There are basically two methods which one could use to construct a navigational pulldown menu in HTML.

Client-side scripting (JavaScript)

Client-side scripting, which usually means JavaScript at present, can be used for programming some actions to be taken by a browser. Thus, when a user makes a selection and then clicks on a button, these actions could be handled as events in a client-side script. Typically, a piece of JavaScript code, embedded into an HTML document by using a SCRIPT element and/or specific attributes like OnClick, would handle the actions so that no form submission takes place but instead the browser does something, e.g. goes to new page. (You could write the code so that it reacts to the mere selection of an option immediately, without anything that looks like form submission.)

In our simple case, the code could be the following. Note that in addition to relying on JavaScript being enabled, this is technically invalid HTML (since it lacks the required ACTION attribute).

<FORM NAME="nav"><DIV>
<SELECT NAME="SelectURL" onChange=
"document.location.href=
document.nav.SelectURL.options[document.nav.SelectURL.selectedIndex].value">
<OPTION VALUE="http://jkorpela.fi/forms/jsnav.html"
SELECTED>Please select an item:
<OPTION VALUE="http://jkorpela.fi/forms/">
Main page on HTML forms
<OPTION VALUE="http://jkorpela.fi/forms/choices.html">
Choices in HTML forms
<OPTION VALUE="http://jkorpela.fi/forms/tables.html">
Tables and forms
<OPTION VALUE="http://jkorpela.fi/forms/methods.html">
Form submission methods (GET and POST)
</SELECT><DIV>
</FORM>

This looks like the following on your current browser:

There are several problems in such an approach, at least if it used alone. For example, many people have JavaScript turned off, and they think they have good reasons for that. See notes on the limitations in JavaScript and HTML: possibilities and caveats.

Even with JavaScript enabled, the construct fails to work with keyboard access, and this is serious to people who cannot use a mouse, for one reason or another. A normal select element can typically be "opened" and traversed using arrow keys, on typical browsers. But for the construct above, as soon as an arrow key is pressed, the first option is immediately selected. This problem could be alleviated by adding a submit button and associating the actions with it rather than the select element; but this would be against the "smoothness" purposes that such menus as used in the first place.

If you, using frames, would like to make the menu open the selected document in a different frame, you cannot use the normal target attribute (as in normal links and in forms handled server-side). Instead you can use parent.framename.location instead of document.location.

Using forms normally (with server-side scripting)

Using server-side scripting, you would use an ACTION attribute which refers to a program which takes the form data as input and directs the browser to a new page which depends on the data. (Whether you call them programs or scripts is irrelevant here; the term server-side script is often used, but it can refer to real compiled programs as well.) The essential thing is that such a program is executed on a server, not by a Web browser. This is what makes this approach browser-independent.

It depends on the specific server-side script how you need to specify the page addresses or other data. The script has been programmed to do something on the basis of name/value pairs in the submitted data, so you need to check the external (interface) documentation of the script.

Liz Knuth has written a very readable description of how to use server-side scripting in this area: How to Make a Dropdown Menu. That document contains several examples with forms that make use of remotely hosted services.

Naturally, if you can run scripts locally, on the server where your Web pages reside, you have more alternatives. Perhaps your server has already got a script installed for the purpose. Or you could try to find a suitable script e.g. from The CGI Resource Index (which has lots of redirection scripts) and install it, or even write a script of your own. The following trivial example of a redirection script in Perl is just an illustration of simplistic code with no checks on the data; it assumes that the destination URL is passed in a field named url.

require "cgi-lib.pl";
&ReadParse(*input);
print "Location: $input{'url'}\n";
exit;
Warning: The examples below originally used VP FreeStuff, a service which has been permanently discontinued (with a Free&Clear as a suggested replacement). Then I replaced them with examples that use another service (SelectURL) which was then discontinued too. This incident is a useful reminder of what I have written in another context:
Of course anyone offering a service for free has the right to discontinue the free service at any time.

Thus, for reliability it is preferable to use either a paid service or, better still, a service running on your own server.

The following HTML form code illustrates how one of the free services, JumpoRama from CGI For Me!, could be used in our example:

<FORM ACTION="http://www.cgiforme.com/jumporama/cgi/jumporama.cgi"
 METHOD="post">
<DIV>
<SELECT NAME="url">
<OPTION SELECTED VALUE="http://jkorpela.fi/forms/">
Main page on HTML forms
<OPTION VALUE="http://jkorpela.fi/forms/choices.html">
Choices in HTML forms
<OPTION VALUE="http://jkorpela.fi/forms/tables.html">
Tables and forms
<OPTION VALUE="http://jkorpela.fi/forms/methods.html">
Form submission methods (GET and POST)
</SELECT>
<INPUT TYPE="SUBMIT" VALUE="Go!">
</DIV>
</FORM>

On your current browser, this would look like the following (and it should be functional):

Using a combined method

It is possible to create a page which uses a combined method so that selection and form submission is handled by JavaScript if supported an enabled, and by a server-side script otherwise.

This may provide some speedup, since the JavaScript code would be executed locally; moreover, when JavaScript is enabled, the functionality would not depend on the accessibility of the server.

Technically, the combined method is a simple combination of the JavaScript method and the server-side method. In our simple example, this means the following:

<FORM ACTION="http://www.cgiforme.com/jumporama/cgi/jumporama.cgi"
 METHOD="post" NAME="nav2">
<DIV><SELECT NAME="url" onChange=
"document.location.href=
document.nav2.url.options[document.nav2.url.selectedIndex].value">
<OPTION VALUE="http://jkorpela.fi/forms/jsnav.html"
SELECTED>Please select an item:
<OPTION VALUE="http://jkorpela.fi/forms/">
Main page on HTML forms
<OPTION VALUE="http://jkorpela.fi/forms/choices.html">
Choices in HTML forms
<OPTION VALUE="http://jkorpela.fi/forms/tables.html">
Tables and forms
<OPTION VALUE="http://jkorpela.fi/forms/methods.html">
Form submission methods (GET and POST)
</SELECT>
<INPUT TYPE="SUBMIT" VALUE="Go!"></DIV>
</FORM>

This looks like the following on your current browser:

This is not valid HTML 4.0 due to the use of the NAME attribute in the FORM tag. You need to use an HTML 4.01 DOCTYPE.(Consult the document JavaScript and HTML: possibilities and caveats for information on the history of this problem.)

For another example of using a combined method, take a look at the HTML source of DefenseLINK, the main page of the official Web site of the U.S. Department of Defense. Yet another example is on the main page of FedEx.

You might alternatively use the following strategy to achieve the situation where a pulldown navigation mechanism is available on JavaScript-enabled browsers, yet the page works without JavaScript too:

Better alternatives to pulldown menus

The obvious: a list of links

Let's begin with the obvious. The functionality of the preceding example could be implemented much simpler as follows:

<UL>
<LI> <A HREF="http://jkorpela.fi/forms/">
Main page on HTML forms</A>
<LI> <A HREF="http://jkorpela.fi/forms/choices.html">
Choices in HTML forms</A>
<LI> <A HREF="http://jkorpela.fi/forms/tables.html">
Tables and forms</A>
<LI> <A HREF="http://jkorpela.fi/forms/methods.html">
Form submission methods (GET and POST)</A>
</UL>

This is a normal list of links, and it looks as follows on your current browser:

Why normal links are better

Using normal links has the following benefits over any approach using a pulldown menu:

  1. It's simple: it uses very basic HTML constructs only.
  2. Therefore, the user knows what to do with it.
  3. It works universally, independently of browser and its settings.
  4. It's as robust as things can be. If a pulldown menu is JavaScript only, it fails whenever the browser has JavaScript disabled. If it uses a server-side script only, it will fail when that server is not running or unreachable e.g. due to maintenance. This is especially a drawback of using a remote server for scripts. Even the combined way of implementing a pulldown menu will fail, when client-side scripting is disabled and simultaneously the server-side script is inaccessible.
  5. It's intuitively clear what it is, as opposite to something that looks like a form submission but isn't.
  6. The user can distinguish between unvisited and (recently) visited links, since most browsers by default use different colors for them.
  7. The user doesn't confuse it with the built-in pulldown menus of the browser (such as menus for setting options, and other menus which relate to the browser, not any particular document).
  8. The user can see all alternatives at a glance, instead of having to invoke a pulldown menu first. Note that pulldown menus aren't always ergonomically well-designed in browsers.
  9. It's faster to use - just one selection of a link (typically, one click) instead of first selecting an alternative, then clicking on a button.
  10. You can add explanatory texts to the alternatives, as plain text after an A element and/or using the TITLE attribute. (You could also attach some illustrating images to them.)
  11. Indexing robots can be expected to follow the links, indexing the documents referred to, when suitable. Due to the great importance of search engines in Web usage, this might be crucial to the findability of your pages. It may also directly affect the ranking of pages by "link popularity". (Indexing robots might conceivably execute actions which simulate submission of forms on Web pages or even execute JavaScript code, but it is hardly realistic to assume that they generally do so!)
  12. You can use HTML markup (such as emphasis) in the link texts, as opposite to the contents of OPTION elements (which must be plain text, by HTML syntax).
  13. You can also use HTML markup around the text links, for example by putting them into a table if you like. Or you could make it a nested list divided into subtopics, or even a sequence of sections, each with its own heading and one or more lists of links under it.
  14. More flexibility: on a typical browser, the user can open a link in a new window (thereby keeping the "navigational" page visible on the screen too) or save the linked document onto a file. Generally, a normal link is more functional than a form which just simulates a normal link.

See Links Want To Be Links (also available as a somewhat older, more styled version at irt.org) for a more detailed explanation of several points mentioned above.

See also Jabob Nielsen's alertbox Drop-Down Menus: Use Sparingly, which discusses the confusion caused by the use of dropdown menus for so many different purposes, and summarizes:

Drop-down menus are often more trouble than they are worth and can be confusing because Web designers use them for several different purposes. Also, scrolling menus reduce usability when they prevent users from seeing all their options in a single glance.

Organizing a set of links in other ways

As the last point above suggests, a simple list is not the only alternative. Thus, the popular counterargument about "eating up" space can easily be refuted in most cases. If the link texts are relatively short, you could just write them one after another, using some suitable separator like the vertical line character | (which works better as a separator than a mere space):

<P>
<A HREF="http://jkorpela.fi/forms/">
Main page</A> |
<A HREF="http://jkorpela.fi/forms/choices.html">
Choices in forms</A> |
<A HREF="http://jkorpela.fi/forms/tables.html">
Tables and forms</A> |
<A HREF="http://jkorpela.fi/forms/methods.html">
Submission methods</A>
</P>

This looks like the following on your current browser:

Main page | Choices in forms | Tables and forms | Submission methods

Can a navigational pulldown menu ever be useful

In special cases a pulldown menu for navigation could make sense, when there is a large number of alternatives. For example, you might have a document where you wish to present, as an aside, a collection of links to some resources discussed in the text. And perhaps you wish to make that compactly so that it does not disturb normal reading.

But before you decide to use a pulldown menu, consider the following:

If you decide to use a pulldown menu with a large number of options, consider the problems briefly mentioned on my page about country selection. A SELECT element with lots of options is always problematic, but you can reduce the problems by using a SIZE attribute greater than 1.

Another special case would be a multidimensional choice. For example, assume that you have a site containing material on various topics and at different levels (such as introductory, basic, advanced, and specialized material), and perhaps in different languages. In such case, you might construct form which acts as a navigational menu containing two or more SELECT elements and one submit elements like the following (which is a non-functional form, just for illustrating how things might look like):

Topic:
Level:
Language:

This might actually be a very good idea for large sites. For some reason, it's seldom seen in action, perhaps because it requires that the site has been organized "orthogonally". Naturally, the you would need a dedicated server-side script which can handle the submitted data by mapping a set of choices to a page address, using information about a uniform naming scheme or a specific mapping table. You might then add JavaScript code which handles the mapping client-side when possible. I have written a sketchy document to illustrate the techniques.

Moreover, for a two-dimensional selection, a table would be a natural choice. It would be just a table of links, with row structure corresponding to topics and column structure corresponding to level, for example. This would be superior to using a the pulldown menu approach when the matrix of documents would be sparse (that is, many of the combinations would lead to nonexisting or dummy documents), since the user would immediately see which combinations are real.