MenuPosition: Smart CSS/Javascript Hybrid Menus

Overview

There are currently two common methods for placing drop-down and fly-out (or slide-out) menus in web designs. One is to use CSS (cascading style sheets) that place the menus and sub-menus when the mouse or other pointing device is held over a top-level menu item. The second is to capture mouse events and use Javascript to display and hide the menus.

CSS placement has the advantage that sub-menus can still function even if Javascript is not supported by the user's browser or has been disabled. It's disadvantage is that sub-menu items may appear beyond the current browser window edges, making them partially or completely inaccessible.

Use of Javascript has the advantage that sub-menus can be placed intelligently, taking into account where it appears in relation to the window edges. The disadvantage is that sub-menus will not appear at all if Javascript is disabled or not supported. 

Brian Katzung of Kappa Computer Solutions, LLC has developed a "smart", CSS/Javascript hybrid menu system called "menuposition" which combines the best of both approaches: basic CSS-based positioning when Javascript is not available or is disabled, and edge-aware Javascript-based positioning when Javascript is available and enabled.

Javascript is also used to overcome a "z-index" stacking issue in Internet Explorer that arises if sub-menus can overlap other menus (e.g. if top navigation drop-downs can overlap left-side navigation and left-side slide-outs can overlap top navigation).

Menu Structure and Javascript Linkage

Menus are structured using HTML nested unordered lists and lists items.

Sub-menus of vertical menus can be set to appear either to the right (for left-side menus) or to the left (for right-side menus), and will automatically reverse direction each time either side would be hit.

First-level sub-menus of horizontal menus are vertical menus and can be set to appear either below or above the horizontal menu, with second and subsequent sub-menus appearing either to the right or left, as above.

In order to avoid page-size-dependent setup overhead at page load time, javascript support uses a just-in-time approach based on mouse-over events at the top level <UL> of each menu (or an enclosing <DIV>).

The script file, menuposition.js, depends on another script from Kappa Computer Solutions, LLC, called viewport.js (based on code from quirksmode.org), and either prototype.js from prototypejs.org or mootools.js from mootools.net.

Configuration

Menu Direction

The direction in which sub-menus appear is determine using one of two methods.

The first (and preferred) method is the use of classes in the top-level <UL> or enclosing <DIV> tag. Horizontal top-level menus should include a class of "mpDown" or "mpUp" to specify whether first-level sub-menus should drop down or raise up from the base menu. Vertical menus, and horizontal menus with the potential to have more than one level of sub-menus, should include a class of "mpRight" or "mpLeft" to specify whether sub-menus should initially be staggered toward the right or left.

If only "mpDown" or "mpUp" is specified, the default for subsequent sub-menus is "mpRight".

A typical menu across the top of a page will have a class of "mpDown mpRight". A typical left-side menu will have a class of "mpRight".

If directional classes are not specified, menuposition will check the "float" style of list items in the menu. If there is a float style of either "left" or "right", the menu is assumed to be horizontal, and "mpDown" is used for the next level of sub-menus. Otherwise, the menu is assumed to be vertical, and "mpRight" is used for sub-menus.

Minimum Sub-Menu Overlap

Menuposition will make sure that sub-menus have at least window.mpMinOverlap pixels of overlap with the parent item (side-to-side if the parent menu is horizontal, or top-to-bottom if the parent menu is vertical). This space is used to guarantee that the user can move the mouse or other pointing device from the parent item to the sub-menu.

Brower Compatibility

The current version of menuposition has been tested with Firefox 1+ and Internet Explorer 6 and 7. It does not currently support work-arounds for versions of IE that don't properly display content overlapping form elements.

Joomla! Integration

Menuposition can be easily integrated into Joomla!-based web sites using Daniel Ecer's extended-menu module and a menu template.