-->
Bookmark and Share

Revenge of the Menu Bar

See the demo page for the finished version of the code.

Constructing the Menus

A similar approach is used for the drop down menus. Each menu will consist of a DIV tag which acts as a container for several item links and possibly some separator bars. As before, style classes as set up for each component of the menu.

div.menuBar,
div.menuBar a.menuButton,
div.menu,
div.menu a.menuItem {
  font-family: "MS Sans Serif", Arial, sans-serif;
  font-size: 8pt;
  font-style: normal;
  font-weight: normal;
  color: #000000;
}

...

div.menu {
  background-color: #d0d0d0;
  border: 2px solid;
  border-color: #f0f0f0 #909090 #909090 #f0f0f0;
  left: 0px;
  padding: 0px 1px 1px 0px;
  position: absolute;
  top: 0px;
  visibility: hidden;
  z-index: 101;
}

div.menu a.menuItem {
  color: #000000;
  cursor: default;
  display: block;
  padding: 3px 1em;
  text-decoration: none;
  white-space: nowrap;
}

div.menu a.menuItem:hover, div.menu a.menuItemHighlight {
  background-color: #000080;
  color: #ffffff;
}

div.menu div.menuItemSep {
  border-top: 1px solid #909090;
  border-bottom: 1px solid #f0f0f0;
  margin: 4px 2px;
}

Absolute positioning is used for the menus DIVs, with visibility set to hidden so that they will initially not appear on the page.

Browser Compatibility

Since these elements are absolutely positioned, you can define them just about anywhere in your HTML source. But to avoid potential problems it's best to place them just after the <BODY> tag or just before the </BODY> tag, outside of any other element.

The DIV for the menu bar is not positioned. It should go where you want it to appear in the page just like any other normal content. However, in IE some combinations of elements and styling in a page can throw off the menu bar position calculated by the script. This often happens when the bar is placed inside a table.

If the menus appear too far below the menu bar, try making the bar relatively positioned:

<div class="menuBar" style="position:relative;">...</div>

Note that the left and top values will default to zero. This often corrects the problem.

For the items, the display:block setting will cause each link to appear below the previous one. Again, both normal and mouseover styles using the :hover pseudo-class are defined for the link tags to achieve a highlight effect.

Separators are built using an empty DIV element with borders to create a groove. The margin settings control the spacing around this groove. Sample HTML is shown below.

<div class="menu">
<a class="menuItem" href="...">Menu 1 Item 1</a>
<a class="menuItem" href="...">Menu 1 Item 2</a>
<a class="menuItem" href="...">Menu 1 Item 3</a>
<a class="menuItem" href="...">Menu 1 Item 4</a>
<div class="menuItemSep"></div>
<a class="menuItem" href="...">Menu 1 Item 5</a>
</div>

At left is the result, with visibility turned on.

The menuItemHighlight class will be used in a way similar to how the menuButtonActive class is used. It will be dynamically added and removed from menu item links via script code when those links have sub menus displayed. This will keep them highlighted even after the mouse moves off of the item.

With this set up, the appearance of the menu components can be changed just by modifying the style definitions. Fonts, colors, borders and spacing can all be modified to create different looks.

Individual buttons, menus and menu items can be added or removed just by editing the HTML code. Also, since each individual menu item is a hypertext link, they can be linked to any URL, specify a target and have event handlers assigned to them just like any normal A tag.

The use of A tags and hover: pseudo-classes for these components also reduces the need for JavaScript code to create mouseover effects.

Additional HTML and styles for sub menus will be covered later. First, we'll start on the script by looking at the code behind the menu bar.

The Script Code

To deal with any incompatibilities in the script, the browser must first be identified.

The following is located at the beginning of the script to set up a global variable called browser which is defined as an object describing the browser name and version.

function Browser() {

  var ua, s, i;

  this.isIE    = false;  // Internet Explorer
  this.isOP    = false;  // Opera
  this.isNS    = false;  // Netscape
  this.version = null;

  ua = navigator.userAgent;

  s = "Opera";
  if ((i = ua.indexOf(s)) >= 0) {
    this.isOP = true;
    this.version = parseFloat(ua.substr(i + s.length));
    return;
  }

  s = "Netscape6/";
  if ((i = ua.indexOf(s)) >= 0) {
    this.isNS = true;
    this.version = parseFloat(ua.substr(i + s.length));
    return;
  }

  // Treat any other "Gecko" browser as Netscape 6.1.

  s = "Gecko";
  if ((i = ua.indexOf(s)) >= 0) {
    this.isNS = true;
    this.version = 6.1;
    return;
  }

  s = "MSIE";
  if ((i = ua.indexOf(s))) {
    this.isIE = true;
    this.version = parseFloat(ua.substr(i + s.length));
    return;
  }
}

var browser = new Browser();

We can then check the browser variable to determine the user's browser and version when needed.