Developer's manual

Creating an expanding menu

Converting UDM into an expanding menu is surprisingly easy. So easy in fact, I found out quite by accident that this is possible at all! If you don't know what I mean by "expanding menu", please have a look at this Expanding menu demo; they're sometimes called "contracting menus" or "switch menus".

An expanding menu can be left or right aligned, absolutely or relatively positioned; it can even be inside a frameset with the links targetting the main frame, as shown in the Expanding menu in a frameset demo.

Here's how to make one:


You should already have the alignment variable set to to "expanding"; if not, please make that change now. The variable is simply a flag for the script's benfit - your navbar will still have flyout menus at this point.

To convert them into expanding menus, there are four steps you need to take:

1. Make the menus open onclick

Expanding menus are opened and closed using onclick events. You can have them work onmouseover if you want, but I think that would be very awkward to use.

For more details about onclick functionality please see: Menus that open onclick; but to summarise for this purpose - you need to add the class name "onclick" to every list-item:

<li class="onclick"><a href="/menu/">About</a>
		<li class="onclick"><a href="/products/">Products</a></li>
		<li class="onclick"><a href="/services/">Services</a></li>

You should add that class name to all of them, even those with no menus attached, because otherwise those items will continue to have mouseover event-handlers that can close other menus. It will also save confusion if and when you add new menus in the future.

The script will handle the return values appropriately - to make sure that "onclick" items which don't actually have a menu still work as regular links - so no worries there.

2. Override the menu positioning

The submenus normally have absolute positioning and margin offsets, so that they sit to the side of the navigation bar, and overlay other content. But here we want them to open directly beneath their parent, and shift the links below them further down.

The script will take care of the menu positioning for you; all you need to do is override the margins, to put them in the right place. Add the following CSS to your page:

/* expanding menu styling */
#udm ul {
	margin-left:0 !important;
	margin-top:1px !important;

The ID-selector and extensive use of !important is so that the rules have enough specificity to override the menus' default styling. You can adjust the margins to tweak the menu position as you prefer.

3. Change the menu behaviors

There are four controllable events which normally reset the menus, but none of them are necessary or desirable for expanding menus. For more details about each handler please read the um.reset documentation, but suffice it to say that for this configuration, you can safely set them all to "no":

//reset behaviors
um.reset = [
	'no',  // reset from document mouse click ["yes"|"no"]
	'no',  // reset from window resize ["yes"|"no"]
	'no',  // reset from text resize ["yes"|"no"]
	'no',  // reset after following link ["yes"|"no"]

In the Expanding menu demo I also have the close timer set to "never", so that the menus don't close onmouseout. You could have delayed-auto-close behavior if you prefer, by setting a value like "5000" (milliseconds).

4. Re-style the menus to suit

Expanding menus are visually 'inside' their parent item, as opposed to 'above' it, so the kind of styling that normally looks great with dropdown menus may not be appropriate - bevelled borders and dropshadow effects could be dropped in favour of simple bordering and a 2-dimensional appearance.

But beside the niceties of design, the main technical consideration is the width of the nested menus: it's okay for dropdown menus to be all the same size, since they're not in the flow of other elements; but expanding menus are, and so each level will need to be progressively smaller to keep the overall width of the navigation bar the same. Since the menus have borders and padding, we're gonna have to think about box-model differences too.

So, we need to define a CSS class for each descendent level, to give each menu the appropriate width. What I've done in the Expanding menu demo is have IE6 in Standards-compliant (sic) mode, and use the simplified box model hack to feed different widths to IE5:

/* expanding menu styling */
#udm ul {
	width:128px !important;
	w\idth:120px !important;

#udm ul ul {
	width:120px !important;
	w\idth:112px !important;
#udm ul ul ul {
	width:112px !important;
	w\idth:104px !important;

/* give all anchors a hand cursor */
#udm a {
	cursor:pointer !important;
	cursor:hand !important;

Notice how I vary the background-color and border-style of child levels, to help provide contrast and to indicate the heirarchy more clearly. I also added a cursor style to the links - normally non-link triggers would have a default cursor, to indicate that you can't click them, but here that distinction is misplaced because everything is clickable.

But please do note, as with all configurations, you should not have non-link menu triggers in the main navigation bar, because for unsupported browsers those links do nothing at all.

That's all the external CSS we need. The rest of the styling is in the udm-custom configuration file as normal.

Additional dynamic behaviors

There are two available extensions which have features specifically designed for expanding menus, and can be used to provide additional dynamic behaviors:

Menu persistence

The Snapshot Cookie extension can save the visual state of menus after each interaction, so that they're persistent on refresh and between page views.

Please see the Snapshot Cookie extension documentation for details and notes on its use.

Contextual navigation

The "You are here" extension tells you where you are in the navigation tree, using visual and link-title semantics, and can be configured to open here-indicated menu branches automatically, hence providing contextual navigation.

This extension cannot be used within a frameset. Please see the "You are here" extension documentation for more details and notes on its use.

Browser notes

This configuration is not supported in Mac/IE5, which doesn't support menus that open onclick. It will only have access to the main navigation bar, not the nested levels.

Accessibility notes

Arrow-key navigation is kinda tricky with expanding menus. It still works, but the distinction between right/left and up/down is no longer accurate - every direction is basically up or down. For two directions of movement, Tab and Shift Tab are perfectly sufficient. So, I would suggest that wherever you document to your users how keyboard navigation works, highlight the Tab key as the most effective way to navigate.

Finally, you should avoid fixed positioning or having the navbar inside a non-scrolling frame: as levels expand the total height of the navbar increases, which might make part of it drop below the fold; if you've used fixed positioning or a non-scrolling frame then the hidden portion will not be accessible to graphical browsers.


We would like your feedback! Take the UDM4 Survey!

UDM 4 is valid XHTML, and in our judgement, meets the criteria for WAI Triple-A conformance.