Introduction
When I first started writing the site in 1999, I didn't realise how many pages I would eventually write. The old menu system consisted of two sets of links on each page, one for the various sections of the site and another set for each page for the section the user was actually in. This was repeated at the top and bottom of each page. This worked quite well but eventually some pages ended up being more menu than content. Not only that but every time I added a page to a section all the links in the pages in that section had to be rewritten. If I added a new section then every page on the site had to have the links changed. Most of the work was done by the excellent Ecobyte's BK ReplaceEm (Internet Archive) - which was later renamed to Replace Text. It was a multi-page, multiple line text search and replace utility. What happened then was that every changed page had to be uploaded to the servers, so I decided to introduce a new menu system.

The original site menu
Concept, Inspiration and Sources
In June 2005, I finally got round to updating the site. I made far more use of CSS, cleaned the layout a bit and looked around for a new menu system. The menu had to consist of one page used throughout the site. Because of the number of sections and pages it should be collapsible and it should be cross-browser, cross-platform compatible. I didn't want to use frames as I want people to be able to bookmark the pages, frames make this next to impossible because the address bar always shows the frameset not the individual page. This meant that for ease of use I had to use iframes.
What I eventually came up with was based on the menus on the pages Folder Tree Menu at Benefit from IT (Internet Archive) and Unobtrusive DHTML, and the power of unordered lists at Kryogenix and the sites listed there. One major problem I had when designing the code is that Microsoft's Internet Explorer 6 did not understand the CSS code position: fixed;. A Google search found the Fixing position:fixed for Windows Internet Explorer page on the Tagsoup site (Internet Archive) and so that code was incorporated into my pages too.
Between the code offered by these sites and my own ideas, what I came up with is the menu shown in the images below:

The 2005 Folder Tree menu
The Folder Tree menu is a sidebar menu and created with HTML, CSS and JavaScript. All sections of the site are listed in a nested ordered list along with a small plus sign gif to indicate that section can be opened - . Each of the section menus can be opened individully by clicking on the link which then opens to show the section content page links. When this happens the plus sign gif is exchanged for a minus sign gif -
- which indicates the open ordered list can be closed again.
Buttons were added to open and close all the sections at once. The width of the sidebar is fixed, and a horizontal scrollbars appears when the menu exceeds this width. A vertical scrollbar appears when the menu exceeds the page height.
The Files
The menu is based on a simple unordered list. When the page is initially opened the full menu is shown, for those with JavaScript enabled the menu will close all the sub-menus. This means that even if JavaScript is disabled the menu is still usable.
Altogether, the menu requires 10 files to work properly, a hideous amount but I can't see how to reduce this number. These files consist of...
2 HTML pages - the calling HTML page such as on the menu HTML
page.
2 JavaScript files - brismenu.js which controls the main functions of the menu and
brismenux.js which controls extras like what happens when the open and close all
buttons are clicked.
3 CSS files - brismenu.css that controls the appearance of the menu, indentations,
which of the images should be displayed and so on. brisie.css that controls the menu
behaviour in Microsoft's Internet Explorer and brisall.css that controls the behaviour
in other browsers.
3 GIF image files, minus.gif and plus.gif
to denominate the open and closed menu items and bullet.gif to denominate individual
pages.
Menu Code
The menu HTML page is a simple unordered list, the only exception to this is that the main list UL has been given the class "mmclickable" and each of the sub lists has been given the class "mopen". The BASE tag is needed so that the chosen menu item appears in the browser window and not the menu div and iframe. The simplified code for the page is...
<!DOCTYPE >
<html>
<head>
...
...
...
<link rel="stylesheet" type="text/css" href="brismenu.css">
<script type="text/javascript" src="brismenu.js"></script>
<script type="text/javascript" src="brismenux.js"></script>
<base target="_top">
</head>
<body>
<input type="button" class="mbtn" onclick=doall("mclosed","mopen"); value="Open
all">
<input type="button" class="mbtn" onclick=doall("mopen","mclosed"); value="Close
all">
<br><br>
<!-- Folders are LI, its items are a nested UL -->
<!-- Default is all open for non JavaScript users -->
<ul class="mmclickable">
<li><a href="..">A document</a></li>
<li><a class="mopen" href="..">Section A</a>
<ul>
<li><a href="..">A document belonging to section A</a></li>
<li><a class="mopen" href="..">A sub-menu (A1) belonging to section A</a>
<ul>
<li><a href="..">A document belonging to sub-menu A1</a></li>
<li><a href="..">A document belonging to sub-menu A1</a></li>
<li><a href="..">A document belonging to sub-menu A1</a></li>
</ul>
</li>
<li><a href="..">A document belonging to section A</a></li>
<li><a class="mopen" href="..">A sub-menu (A2) belonging to section A</a>
<ul>
<li><a href="..">A document belonging to sub-menu A2</a></li>
<li><a href="..">A document belonging to sub-menu A2</a></li>
</ul>
</li>
<li><a href="..">A document belonging to section A</a></li>
</ul>
</li>
<li><a class="mopen" href="..">Section B</a>
<ul>
<li><a href="..">A document belonging to section B</a></li>
<li><a class="mopen" href="..">A submenu (B1) of section B</a>
<ul>
<li><a href="..">A document belonging to sub-menu B1</a></li>
<li><a href="..">A document belonging to sub-menu B1</a></li>
<li><a href="..">A document belonging to sub-menu B1</a></li>
</ul>
</li>
<li><a href="..">A document belonging to section B</a></li>
</ul>
</body>
</html>
Calling Code
Each content page has certain code in common. This is the code that calls the css file, brisray.css, that contains the display code for the content pages. The rest of the code calls brisie.css and brisall.css that ensures the menu stays fixed in the browser window in IE and all other browsers. The DIV tags splits the page up so that the menu iframe can be displayed in one and the content in the other.
<!DOCTYPE>
<html>
<head>
...
...
...
<LINK rel="stylesheet" type="text/css" href="../common/brisray.css">
<!-- The code below fixes the menu bar in IE and other browsers. -->
<!-- The style absolute: fixed is not handled equally well by all browsers -->
<STYLE type=text/css media=screen>@import url( ../common/brisall.css );</STYLE>
<!--[if IE]>
<LINK media=screen href="../common/brisie.css" type=text/css rel=stylesheet>
<SCRIPT type=text/javascript>
onload = function() { content.focus() }
</SCRIPT>
<![endif]-->
</head>
<BODY>
<DIV id=menubar><iframe id=menufrm src="../common/menu.htm"></iframe></DIV>
<DIV id=content class="ctr nrmltxt">
...
...
...
</div>
</body>
</html>
brismenu.js
The code in this file collapses, if JavaScript is enabled, the menu as soon it is opened by renaming the class "mopen" to "mclosed" and processes the images so that they are clickable along with the href's.
/*
mmclickable.js
Converts an unordered list to an explorer-style tree, with clickable
icons
To make this work, simply add one line to your HTML:
<script type="text/javascript" src="mmclickable.js"></script>
and then make the top UL of your nested unordered list of class
"mmclickable".
*/
addEvent(window, "load", makeTreesC);
function makeTreesC() {
// We don't actually need createElement, but we do
// need good DOM support, so this is a good check.
if (!document.createElement) return;
uls = document.getElementsByTagName("ul");
for (uli=0;uli<uls.length;uli++) {
ul = uls[uli];
if (ul.nodeName == "UL" && ul.className == "mmclickable") {
processULELC(ul);
}
}
}
function processULELC(ul) {
if (!ul.childNodes || ul.childNodes.length == 0) return;
// Iterate LIs
for (var itemi=0;itemi<ul.childNodes.length;itemi++) {
var item = ul.childNodes[itemi];
if (item.nodeName == "LI") {
// Iterate things in this LI
var a;
var subul;
subul = "";
for (var sitemi=0;sitemi<item.childNodes.length;sitemi++) {
var sitem = item.childNodes[sitemi];
switch (sitem.nodeName) {
case "A": a = sitem; break;
case "UL": subul = sitem;
processULELC(subul);
break;
}
}
if (subul) {
associateELC(a,subul);
} else {
a.parentNode.className = "mbullet";
}
}
}
}
function associateELC(a,ul) {
if (a.parentNode.className.indexOf('mopen') == -1)
a.parentNode.className = 'mclosed';
a.onclick = function () {
this.parentNode.className = (this.parentNode.className=='mopen') ? "mclosed" : "mopen";
return false;
}
}
/* Utility functions */
function addEvent(obj, evType, fn){
/* adds an eventListener for browsers which support it */
if (obj.addEventListener){
obj.addEventListener(evType, fn, true);
return true;
} else if (obj.attachEvent){
var r = obj.attachEvent("on"+evType, fn);
return r;
} else {
return false;
}
}
brismenux.js
The code in this file provides functionality for the open and close all buttons on the menu page. All it really does is, depending on what button was clicked, rename the class "mopen" to "mclosed" or vica versa.
function doall(currentclass, newclass){
// Open or close all menu items
// Look for all LI elements
uls = document.getElementsByTagName("li");
for (uli=0;uli<uls.length;uli++) {
ul = uls[uli];
// Check and change the class name
if (ul.nodeName == "LI" && ul.className == currentclass) {
ul.className = newclass;
}
}
}
brismenu.css
This file controls the indentation and margins of the menu items, adds the appropriate image as part of the URL so that they become clickable, shows or hides the menu items depending on the class "mopen" or "mclosed" as well as doing the usual CSS things like setting the colours.
body { background-color: #66FF99; }
/* Buttons */
.mbtn { background-color: #66FF99; }
/* Turn off list bullets */
ul.mmclickable li { list-style: none; }
/* Set the ul indents */
ul.mmclickable ul { padding-left: 10px; margin-left: 10px; }
/* Set left hand main margin */
ul.mmclickable { margin-left: 3px; padding-left: 3px; }
ul.mtreeclickable, ul.mtreeclickable ul, ul.mtreeclickable li { margin: 0;
padding: 0; }
/* Provide space for our own "bullet" inside the link */
ul.mmclickable li a { padding-left: 20px; }
/* Show "bullets" in the links, depending on the class of the
LI that the link's in */
ul.mmclickable li.mopen a {
background: url(minus.gif) top left no-repeat;
}
ul.mmclickable li.mclosed a {
background: url(plus.gif) top left no-repeat;
}
ul.mmclickable li.mbullet a {
background: url(bullet.gif) top left no-repeat;
}
/* Actually show and hide sublists */
ul.mmclickable li.mopen ul { display: block; }
ul.mmclickable li.mclosed ul { display: none; }
In the preceeding code you'll notice that some elements such as the ul indents and margins have both the margin-left and padding-left set. This is because of the way in which some browsers work.
The intended and default spacing
If only margin-left is used then Windows MSIE 6.0.29 and Opera 7.54, MAC MSIE 5.2 show the intended spacing. Windows Mozilla Firefox 1 and Netscape Navigator 7.2, Mac Netscape Navigator 7.2 and Safari 1.0.3 and Linux Konqueror 3.4.1 and Linux Epiphany 1.7.1 show the default. If only padding-left is used then the situation is reversed.
brisie.css
Microsoft's Internet Explorer will not recognise the CSS code position: fixed; as other browsers do. This file ensures that it does.
BODY {
OVERFLOW: hidden; HEIGHT: 100%
}
DIV#content {
OVERFLOW: auto; WIDTH: 100%; HEIGHT: 100%
}
brisall.css
This file is for all browsers except Microsoft's Internet Explorer.
BODY {
PADDING-RIGHT: 0px; PADDING-LEFT: 200px; PADDING-BOTTOM: 0px; MARGIN: 0px;
PADDING-TOP: 0px
}
DIV#menubar {
BACKGROUND: #ddd; LEFT: 0px; OVERFLOW: hidden; WIDTH: 200px; POSITION: absolute;
TOP: 0px; HEIGHT: 100%
}
DIV#content {
PADDING-RIGHT: 10px; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; PADDING-TOP: 10px
}
@media Screen
{
UNKNOWN {
POSITION: fixed
}
}
bullet.gif
This is the image for individual documents in the menu.
plus.gif
This is the image to show that the menu item can be opened to show more items.
minus.gif
This is the image to show that part of the menu tree can be closed.
Problems and To Do's
For the amount of time it's taken to get this menu to work at all there are still some problems with it.
1) Separate CSS files are needed to get around the problem that Microsoft's Internet Explorer has with position: fixed; This adds to the complexity of the project.
2) WebTV users have particular problems with the menu. This looks like because of WebTV's inability to render CSS, JavaScript and even some HTML properly.

How WebTV users see the menu and page contents
3) When I decided against frames I introduced another problem. By using an iframe the frame contents are refreshed every time a visitor opens a new page. When this happens the visitor loses whatever view of the menu they had on the previous page. The Benefit from IT site gets around this by using a cookie. I should look into doing something similar. Another way of passing information from page to page is by using variables in the URL, I shall look into this as well.
Despite these problems, in 2025, the menu still works and is still being updated as not all the pages that use it have not yet been updated to use the newer menus I use.
Sources & Resources
Replace Text (BK ReplaceEm) Echobyte (Internet Archive)
Fixing position:fixed for Windows Internet Explorer - Tagsoup (Internet Archive)
Folder tree menu based on CSS and unordered lists (ULs) - Benefit from IT (Internet Archive)
Unobtrusive DHTML, and the power of unordered lists - Kryogenix