Developer's manual

Core configuration

These arrays control the fundamental layout and behaviors.

um.baseSRC

Path to images folder.

JS/ASP
//path to images folder
um.baseSRC = '/udm-resources/';
PHP
//http path to images folder (from the web root, not the server root)
$um['baseSRC'] = '/udm-resources/';

You only need to set a value here if you're using images in the navbar or menus - as backgrounds, dropshadows, or submenu-indicator arrows. If you are using images, use this value to specify a path to the udm-resources folder (or wherever you have the images).

If all your pages are in the same folder, a relative path is fine. But if your site spans multiple folders (as is more likely), you will need to set this to an absolute or root path - such as "http://www.domain.com/udm-resources/" or "/udm-resources/". Whether you're using a client-side or server-side configuration, this variable defines an HTTP path - a path from the web root, not the server root.

If that's not possible you can re-define it on a page-by-page basis, by adding snippets like this between the udm-custom.js and udm-control.js script includes:

<script type="text/javascript" src="../pathto/udm-resources/udm-custom.js"></script>
<script type="text/javascript">

	//path to images folder
	um.baseSRC = '../pathto/udm-resources/';

</script>
<script type="text/javascript" src="../pathto/udm-resources/udm-control.js"></script>

You can only do that if you're using the javascript configuration - but if you're using a server-side configuration then defining a web root path shouldn't be a problem in the first place.

For any configuration, if your pages use SSL and you define this as an absolute path, you must use an https:// path, otherwise the pages will be deemed mixed content and hence generate a secure/insecure items dialog.

um.trigger

Initialization trigger element.

JS/ASP
//initialization trigger element ["id"]
um.trigger = 'brothercake';
PHP
//initialization trigger element ["id"]
$um['trigger'] = 'brothercake';

Defining a trigger element allows the menu script to initialize before window.onload. But for the sake of backward compatibility, this feature is not enabled by default.

To enable it you simply specify the ID of another element (apart from the root menu <ul>) that will also exist on every page which contains the menu, and which comes at or later in the source code than the last <li> in the menu tree. As soon as this element is found, the menu will begin to initialize, thereby removing its dependency on the loading of images and other external files.

The trigger element must be at or later in the source code than the last <li>, otherwise the tree will be incomplete and won't initialize properly (if at all). But this of course means you can use the last <li> itself as the trigger element, and that's what I'm doing on this site - it makes for a nicely self-contained structure, that "triggers itself", as it were:

	<li id="brothercake"> ... </li>
</ul>

If you don't specify a trigger element, or the element can't be found, the script will simply fall-back on the original, encapsulated onload handler. This is also what will happen for Mac/IE5, which doesn't support this technique. If you want all browsers to do that you can remove the um.trigger property, or set it to an empty string.

If you're doing any additional scripting with the API, please note that there are implications of initializing before window.onload on such scripting. For more about this technique in general please see: domFunction - using scripts before window.onload

um.orientation

Navbar orientation.

JS/ASP
//navbar orientation
um.orientation = [
	'vertical', // alignment ["vertical"|"horizontal"|"popup"|"expanding"]
	'left',     // h align ["left"|"right"|"rtl"]
	'top',      // v align ["top"|"bottom"]
	'absolute', // positioning ["relative"|"absolute"|"fixed"|"allfixed"]
	'0.6em',    // x position ["em"|"ex"|"px"|"0"]
	'0.7em',    // y position ["em"|"ex"|"px"|"0"]
	'1000',     // z order ["0" to "10000"]
	];
PHP
//navbar orientation
$um['orientation'] = array(
	'vertical', // alignment ["vertical"|"horizontal"|"popup"|"expanding"]
	'left',     // h align ["left"|"right"|"rtl"]
	'top',      // v align ["top"|"bottom"]
	'absolute', // positioning ["relative"|"absolute"|"fixed"|"allfixed"]
	'0.6em',    // x position ["em"|"ex"|"px"|"0"]
	'0.7em',    // y position ["em"|"ex"|"px"|"0"]
	'1000',     // z order ["0" to "10000"]
	);
alignment ["vertical"|"horizontal"|"popup"|"expanding"]

The navbar can be a "vertical" column or a "horizontal" row.

It can also provide "popup" menus from events on other page elements - see Using popup menus for more about that.

And it can be configured as an "expanding" menu - please see Creating an expanding menu for details.

h align ["left"|"right"|"rtl"]

Specify "left", "right" or "rtl" alignment.

A value of "rtl" is essentially the same as "right", except that it also changes the writing-mode, so you can use the menu with right-to-left or bi-directional text. If you have a horizontal navbar then RTL mode will automatically invert the list (so that the links flow from right to left) which in fact happens naturally through the use of float:right. In RTL mode, then, a horizontal navbar is always anchored from the right edge of the page.

In standard LTR mode, a horizontal navbar is similarly always anchored from the left edge of the page, even if you've set it to be right-aligned. That's because right-alignment of a horizontal navbar isn't actually supported, except in RTL mode. The only way to implement it (without knowing the width of the navbar in advance, which we don't) would be to use float:right on the list-items, like we did for RTL mode, but that's not a useable solution here - it completely breaks in Mac/IE5, and Opera 5 and 6. In RTL mode that doesn't matter, because they don't support RTL languages anyway.

So, if you apply right alignment to a horizontal navbar in LTR mode, the navbar will still be anchored from the left, but nonetheless the menus will open from the right - what you might call pseudo-right alignment. What you can then do for your own (known) layouts, is set a fixed width on the navbar and implement right alignment manually. Something like this:

#udm {
	width:30em;
	left:100%;
	margin-left:-30em;
	}

Similarly, if you want center alignment you can put a relatively-positioned, left-aligned navbar inside a fixed-width, center-aligned container; like this demo: Center-alignment demo.

v align ["top"|"bottom"]

Specify "top" or "bottom" vertical alignment.

With an absolutely-positioned navbar, bottom alignment is pretty much unuseable, because of massive inconsistencies in how it's interpreted - in Mac/IE5 and some Opera 7 builds, the navbar is placed at the bottom of the page; in most other supported browsers it's the bottom of the viewport; in Opera 5 and 6 it doesn't work at all, and the navbar is placed at the top.

But with a relatively-positioned horizontal navbar that has "0" for the y position, bottom alignment appears no different from top alignment, except that the menus now open above the navbar, instead of beneath it - what you'd probably call dropup menus.

positioning ["relative"|"absolute"|"fixed"|"allfixed"]

You can specify "relative", "absolute" or "fixed" CSS positioning. What you choose here is rather fundamental, so if you're not sure, please read Choosing a positioning mode.

CSS position:fixed is not supported in Internet Explorer 5 or 6, and is too unstable to apply for Mozilla Gecko browsers earlier than 1.3b (Netscape 7.1). However for Win/IE5-6 the script includes javascript emulation, which you can have in addition to standard fixed position for other browsers, by specifying the value "allfixed". Fixed position demo.

If you don't use the emulation (or in those older mozilla builds, or if scripting is not available), fixed positioning degrades to absolute positioning. But that being the case, you should avoid putting a fixed navbar inside another positioned container - fixed positioning is not contextual with its parent the way absolute positioning is, so you could end up with a huge cross-browser discrepancy.

x position ["em"|"ex"|"px"|"0"]

The left or right position of the navbar, which can be specified in any valid CSS unit except percentage (because it doesn't work right in IE). Negative values are not supported. You cannot exclude the unit unless the value is "0".

Although you can use "ex" units, I wouldn't recommend them, because browsers have very different ideas about how big they are.

y position ["em"|"ex"|"px"|"0"]
The top or bottom position of the navbar, which can be specified in any valid CSS unit except percentage (because it doesn't work right in IE). Negative values are not supported. You cannot exclude the unit unless the value is "0".
z order ["0" to "10000"]
The z-index (stacking order) of the navbar, which must be less than "10000" because the menus can use up to 20,000 levels for themselves.

um.list

Navbar list output.

JS/ASP
//navbar list output
um.list = [
	'flexible', // horizontal overflow ["rigid"|"flexible"]
	'yes',      // -SPARE-
	'no',       // -SPARE-
	];
PHP
//navbar list output
$um['list'] = array(
	'flexible', // horizontal overflow ["rigid"|"flexible"]
	'yes',      // -SPARE-
	'no',       // -SPARE-
	);
horizontal overflow ["rigid"|"flexible"]

This controls the behavior of a horizontal navbar when there isn't enough space for its full width:

Rigid overflow
With "rigid" overflow the navbar maintains a single row, and will force a horizontal scrollbar if the window is too small.
Flexible overflow
With "flexible" overflow the navbar collapses into multiple rows as the window size decreases.

The rigid setting will keep the navbar straight, providing that its container doesn't have a fixed width - it isn't "strong" enough to force a fixed-width element to expand.

Flexible overflow would suit a relatively-positioned navbar, because it's part of the document flow, and so other content will move to accomodate its increased height. But an absolutely-positioned navbar isn't part of the flow, so rigid overflow probably makes more sense there, to avoid navbar items overlapping other page elements. For more about positioning, please see Choosing a positioning mode.

This behavior relies on javascript - when scripting is not available it will have the default value "flexible".

However controllable overflow isn't supported either way in Konqueror 3.1 or earlier, or in Opera 5 or 6 - with the former it's always "flexible", the latter always "rigid".

- SPARE -

This used to be the show menus to IE-based screenreaders control, but it's been retired in Version 4.4 because it no longer seems appropriate. From 4.4 onwards, the menus are accessible to any browser-based reader using Opera, Mozilla, Safari, Konqueror, or Windows Internet Explorer.

Please see Notes about browser-based screenreaders for more details.

- SPARE -

This used to be the hide static menus for netscape 4 control, but it's been retired in Version 4.4 because it no longer seems relevant. From 4.4 onwards it defaults to "no".

um.behaviors

Menu behaviors.

JS/ASP
//menu behaviors
um.behaviors = [
	'200',     // open timer ["milliseconds"|"0"]
	'500',     // close timer ["milliseconds"|"never"|"0"]
	'yes',     // reposition menus to stay inside the viewport ["yes"|"no"]
	'default', // manage windowed controls for win/ie ["default","hide","iframe","none"]
	];
PHP
//menu behaviors
$um['behaviors'] = array(
	'200',     // open timer ["milliseconds"|"0"]
	'500',     // close timer ["milliseconds"|"never"|"0"]
	'yes',     // reposition menus to stay inside the viewport ["yes"|"no"]
	'default', // manage windowed controls for win/ie ["default","hide","iframe","none"]
	);
open timer ["milliseconds"|"0"]
The open timer sets a delay in milliseconds from when you mouseover a link, to when its menu opens. If you move off that link before the timer is up, the timer is cancelled and the menu doesn't open. This improves usability by effectively filtering casual mouse movement, and more specifically so that when moving the mouse from a link to a menu, you can pass briefly over intervening links without closing the menu you're going to.
close timer ["milliseconds"|"never"|"0"]

The close timer sets a delay in milliseconds from when your mouse leaves a menu, to when it closes. If you move back onto the menu before the timer is up, the timer is cancelled and the menu doesn't close. This improves usability by allowing mouse movement to be imprecise.

You can also set a value of "never", which allows you to create persistent menus - menus that only close from a document onclick, rather than from menu mouseout. But be aware that clicking the document to close the menus doesn't work in Mac/IE5.

Open and close timers only apply to mouse navigation - when navigating with the keyboard the menus open and close straight away - timers are unecessary for keyboard navigation; counter-productive, even.

reposition menus to stay inside the viewport ["yes"|"no"]

If set to "yes" then the menus will automatically reposition themselves, so that they're always inside the visible browser window. This gives you the freedom to create large menu structures, or position menus close to the edge, without them becoming inaccessible.

But if for any reason you want to exclude an individual menu from the repositioning routine, you can do so by giving that <ul> the class name "nomove".

This is not supported in Win/IE5.0 with a relatively-positioned vertical navbar - because the property values it needs are not reliably available.

manage windowed controls for win/ie ["default","hide","iframe","none"]

This controls what the script does to prevent <select> elements and other windowed controls from showing through the menus in Win/IE5-6. There are two basic techniques - the iframe shim that works in IE5.5-6, and the classic technique of making <select> elements invisible when the menus are open.

You can specify which combination of techniques to use, as follows:

"default"
Use the iframe technique for IE5.5-6 and the visibility technique for IE5.0
"hide"
Use the visibility technique for all versions
"iframe"
Use the iframe technique for IE5.5-6 and do nothing for IE5.0
"none"
Do nothing

If set to "default" or "hide" then all browsers will have explicitly visible <select> elements, for the sake of consistency. Other things being equal, "default" is the optimum setting, but there may be circumstances where the <iframe> technique is not appropriate:

  1. It actually invalidates the DOM on the fly, because the <iframe> has to be appended to a list-item, which is not allowed to contain one. But it is temporary, and this is just IE we're talking about - it won't prevent your pages from validating, and most importantly, the DOM that conformant user-agents see is always correct.
  2. The <iframe> is rendered invisible using an opacity filter, so that menus can still contain transparent or semi-transparent content. There are two issues with this - firstly that it's invalid CSS; secondly that filters are an Active-X control (at the same security level as plugins like Flash), so for anyone who has Active-X disabled completely the <iframe> will have a white background.
  3. If you use the ebay toolbar it may cause the menus to respond more slowly.

If any of those issues affect you, use "hide" or "none" instead.

The iframe shim can safely be used on SSL pages, without triggering the "secure/insecure items" dialog in Win/IE.

um.reset

Reset behaviors. These allow you to control whether certain events will send a reset command - in other words, close all menus and clear all highlighted links.

JS/ASP
//reset behaviors
um.reset = [
	'yes', // reset from document mouse click ["yes"|"no"]
	'no',  // reset from window resize ["yes"|"no"]
	'yes', // reset from text resize ["yes"|"no"]
	'no',  // reset after following link ["yes"|"no"]
	];
PHP
//reset behaviors
$um['reset'] = array(
	'yes', // reset from document mouse click ["yes"|"no"]
	'no',  // reset from window resize ["yes"|"no"]
	'yes', // reset from text resize ["yes"|"no"]
	'no',  // reset after following link ["yes"|"no"]
	);
reset from document mouse click ["yes"|"no"]

This reset has an important usability purpose for dropdown or flyout menus: the menus are absolutely positioned and hence overlay other content, so the user must have an obvious and intuitive way of making them "go away".

You must not turn this off unless your menus do not overlay other content, such as with an expanding menu. However it's not supported either way in Mac/IE5.

reset from window resize ["yes"|"no"]

This reset is partly to prevent situations where menus would become obscured and create scrollbars, and partly for visual integrity: the menus are positioned on the fly, so with a relatively-positioned navbar inside a fluid design, or one which is positioned in percentages, they would become misaligned with respect to their parent as the window size changes.

You should not turn this off unless your navbar is absolutely-positioned, or the menus are not absolutely positioned (such as with an expanding menu).

reset from text resize ["yes"|"no"]

This reset is for visual integrity: the menus are positioned on the fly based on the dimensions of their parent; the menu dropshadows are separate layers which are also created and positioned dynamically; if the menus do not reset when the text size changes, you will see the menu and shadow layers become misaligned with respect to each other and their parent.

You should not turn this off unless your menus are not absolutely positioned, such as with an expanding menu.

This reset applies after you click an active link, and is not normally required. It's here for the benefit of menus which link to an <iframe> or similar, to prevent overlapping menus from obscuring the embedded page.

It's unecessary on normal (self-targetting) pages, because once you've clicked a link you'll be going to a new page anyway. You may be inclined to turn it on for the sake of visual closure, but I recommend that you don't - I think it's helpful to see a reminder of where you're going to as the page unloads.

um.hstrip

Horizontal continuation strip. This creates a visible strip beneath the navbar, which is the <ul> itself at 100% width - either the document width, or the width of the navbar's container. Neither of these values will have any effect on a vertical navbar.

JS/ASP
//horizontal continuation strip
um.hstrip = [
	'none', // background ["color"|"#hex"|"rgb()"|"image.gif"|"none"]
	'yes',  // copy item margin-right to margin-bottom ["yes"|"no"]
	];
PHP
//horizontal continuation strip
$um['hstrip'] = array(
	'none', // background ["color"|"#hex"|"rgb()"|"image.gif"|"none"]
	'yes',  // copy item margin-right to margin-bottom ["yes"|"no"]
	);
background ["color"|"#hex"|"rgb()"|"image.gif"|"none"]

Specify the continuation strip background, as a colorname, a hex or rgb color value, or an image. Images can be GIF, JPEG (JPG), PNG, MNG or BMP.

Set this to "none" if you don't want a visible continuation strip.

copy item margin-right to margin-bottom ["yes"|"no"]

The margin between items in a horizontal navbar is margin-right. If you set this variable to "yes" then the margin will be applied to margin-bottom as well.

This makes the navbar look nicer when split into multiple rows, which can happen if you use flexible horizontal overflow. But of course it makes the background slightly taller than the links, so if you have a visible continuation strip you may prefer to set this to "no".

In Internet Explorer and Opera 7, when using an absolutely-positioned navbar with the <ul> a direct child of the body, the computed width of 100% is minus any document margins or padding, so it might not be quite wide enough. If you have this issue you can work around it with CSS - set your margins and padding to 0 so the problem doesn't manifest:

html,body {
	margin:0;
	padding:0;
	}

There are also some browser caveats to bear in mind:

  1. In Mac/IE5 when using a relatively-positioned navbar within a table-based layout, the navbar float takes it fatally outside the document flow - the surrounding <td> will have no height, which can send the rest of the page out of alignment.

    So if you use this configuration and layout you should disable the continuation strip to avoid these issues - set the background to "none". It's no loss in this case, because you can use <td> background to exactly the same effect.

  2. In Mozilla Gecko builds 0.9.4 (Netscape 6.2) or earlier, when using an absolutely-positioned navbar, the height of the strip has to be maintained with javascript, so it won't be visible when scripting is disabled, nor increase in height when using flexible horizontal overflow.
  3. In Konqueror 3.1 or earlier, when using an absolutely-positioned navbar, the continuation strip is not supported.

Search

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.

-