Dynamic Drop Down Menu

Site Navigation 

Scripted drop-down navigation menus commonly appear on web sites. There are numerous issues relating to the use of such scripts that are as often as not ignored by their authors and/or the individuals responsible for deploying them. This is often out of ignorance of those issues, or an unwillingness to recognise anything outside of the individual's personal experience, or out of a belief that they do not apply in the context of use (which may actually be true in some cases). Alternatively the author may be aware of the issues and just not know how to tackle them.

I have never had to write a proper dynamic drop-down navigation menu so I thought I would have a go at doing so, and see to what extent I could address the issues involved. This page features that menu, above.

This site has no real need of such involved navigation so the links in the menu above all refer to parts of comp.lang.javascript Usenet newsgroup FAQ, just for the sake of having something to link to in this example.

The first, and probably most significant, issue with scripted drop-down navigation menus is their dependency on javascript to operate as intended. But the problem goes beyond the mere operation of the menu to the consequences of the failure of the menu whenever javascript is unavailable on the client, or the client doesn't support the features required by the menu script (which are usually fairly demanding of a web browsers in terms of its dynamic capabilities).

Many scripts are designed such that the navigation items, links, submenus, etc. are defined in javascript data structures. As a result, when they fail there is no navigation menu and no links appear on the web page. The result of the failure of the script is of absolutely no value to the user at all, but worse than that (if making a web site unavailable to a user was not bad enough), search engines do not execute javascript that they find on a web page, and only see what the user of a javascript disabled/incapable browser would see. When search engines cannot see any navigation at all they cannot index the site, which is not very good for search engine rankings.

Several strategies can be used to address this issue. One common approach is to provide alternative navigation in addition to the drop-down menu. This can be as simple as a single link to a site map page that itself links to all other pages on the site (or through a hierarchical scripture of dedicated navigation pages. This deals with the search engine problem entirely as it does allow indexing of the entire site, but it is not so convenient for human users.

An alternative approach, and the one used here, is to define the navigation in the HTML and then use the script to manipulate the HTML into the drop-down menus. Suitably cautious and defensive scripting can arrange to only attempt to manipulate the underlying HTML when it can be certain of success, so all failures, including the client not supporting scripting at all for any reason, leaves the navigation on the page where it can be employed directly. I have used structures of nested unordered lists in the HTML to define the menu contents. Nested DV elements are also commonly used, though they lack the semantic appropriateness of nested lists in this context.

For reasons that I will explain later, there is an image link to the right of the menu headers that can be used to re-load the page with the drop-down menu script disabled (assuming that it is currently active). This can be used to demonstrate how the navigation would be displayed to the users of javascript disabled/incapable, and less dynamic, browsers, as an alternative to actually viewing the page in such a browser.

The next issue that needed to be tackled was the inherent fluidity of HTML. The user may re-size the browser, or change the font size settings at any time. Many drop-down menu scripts try to pin down the menu size and placement in order to avoid dealing with the fluidity of HTML. These attempts to impose rigidity of the menu components generally fail (at least in non-IE browsers), and such scripts tend to fall apart whenever the user succeeds in changing the font size.

The user's ability to choose their preferred font size is a considerable aid to usability and scripts should not be written such that they cannot cope when it happens. This script attempts to compensate for any changes in font size, and adapt to re-sizing of the window (including presenting its sub-menus in scrollable DIVs if they cannot be accommodated within the viewable area of the user's browser window).

Another requirement, even more related to accessibility than the user's ability to change font size, is keyboard navigation. Unfortunately there are no standards for the navigation of drop-down menus, and that presents a usability issue in itself. Adopting the conventions of, for example, any one operating system, would act against usability for those used to other operating systems.

My choice has been to use the link navigation conventions common to browsers. Commonly the tab key advances through the navigation links and the combination of shift-tab goes backwards. As these actions will (mostly) focus the links in a browser, and as the menu headings are (at least become) links, The arrangement is that when a link that is a heading for a sub-menu is focused it opens the sub-menu, unless it is focused by a shift-tab sequence, which closes any already open sub-menu. This is sufficient for using the keyboard to navigate the menu, but it can be inconvenient to use. So, in addition, activating the menu header links (commonly with the return key), will close an open sub-menu, or open a closed one. (currently this aspect of keyboard navigation is not fully functional on Konqueror (and probably Safari).)

Another accessibility issue, that is difficult for scripts to automatically accommodate, is the combination of script capable browsers and screen readers (or speech browsers). How is a screen reader expected to handle a section of the page suddenly becoming visible, etc? As this condition cannot be detected by a script the best strategy available is to offer the user the opportunity to disable the drop-down menu, reverting to the unordered list structure in the underlying HTML (something that screen readers and speech browsers should easily accommodate).

To this end, one of the last tasks performed by this menu script, when it believes that it is going to be fully supported by the browser, is to insert an additional link that can be used to re-load the page with the menu disabled (and placing it in the tab-index order before the menu headers). Obviously the provision of this option also provides an escape mechanism for the users of other browsers who are, for any reason, unhappy with the dynamic drop-down menu.

For various reasons I am presenting this script rather sooner than I normally would. It has not yet been properly tested, it, for example, hasn't yet been seen by any Mac browsers, and there are still issues with it that I know about. Such as: IE 5.0 doesn't properly position the first sub-menu in any but the first row whenever the top-level menu headers wrap onto more than one line and keyboard navigation doesn't work that well in Konqueror 3. I can probably solve most of those outstanding issues.

I am also yet to put the mechanism in place for detecting the browser's willingness to follow the CSS settings made by the script (such as Opera in small-screen mode), and user style-sheet overridden style settings), and aborting the script in response. That is not particularly difficult but I need to resolve the other issues first because those tests depend on the final structure of the modified DOM.

© Richard Cornford 2004