sCSS-guide, the extra page I as one big page
More advice for the full screen mode.
I list below all topic groups, which I have done according to subjects, which they handle. You can return to this topic group by using this menu and the link Table of topic groups on the top of the each page.
To the normal page

I How to design dynamic menus

Nature pages


I have divided this page into sections, which handle following topics:

The content as a one big page


This page gives hints to create multilevel dynamic menus. In the presentation section is also advice, which can be applied also for static menus.

How to design dynamic menus worked at the beginning only certain versions of Netscape and MS IE browsers with proprietary JavaScript-encoding, which was given the name DHMTL (Dynamic Hyper Text Markup Language). After that time scripting, which creates for example dynamic menus standardized in the DOM-specifications (Document Object Model) by W3C. The standard scripting language is ECMAScript and JavaScript encoding is standard as much as it conforms with ECMAScript standards.

ECMA: ECMAScript language binding; W3C: Document Object Model (DOM) Level 1 Specification (Version 1.0, W3C Recommendation 1 October, 1998), Document Object Model (DOM) Level 2 Core Specification (Version 1.0, W3C Recommendation 13 November, 2000).

Newest browsers support DOM at various level. The best implementations are in newest MS IE, Mozilla Gecko browsers (for example Netscape 6.1+) and Opera 7.x browsers. Also Opera 4.x-6.x browsers have experimental support of DOM. The used JavaScript works in Opera 4.x and it supports necessary CSS-features but according to my experience the generic functionality of dynamic menus is bad. It is quite working in Opera 5.x-6.x browsers, but all DOM-based menus don't work in them. They support also some extensions of MS IE.

Because it is fully possible to create dynamic menus, which work at least in MS IE 4.x+ for Windows, MS IE 5.x+ for Mac, Netscape 4.x and Opera 5.x+ browsers, I concentrate in this page to give hints in order to create dynamic menus, which work in the previous mentioned browsers. How to design dynamic menus might work also older versions of MS IE for Mac, but I don't have any information about the functionality of the menus in these browsers.

Scripts which have been designed only for the Netscape 4.x series browsers don't work in Mozilla Gecko browsers, because Netscape 4.x use in dynamic menus the proprietary method document.layers(), which is not supported in Mozilla Gecko browsers. They don't support either proprietary Netscape 4.x LAYER and ILAYER elements (it is in principle possible to use with them the element IFRAME but I don't regard using it very reasonable because of some problems). How to design dynamic menus should be made by using the method document.getElementById() (maybe in some situations getDocumentElement() could be used too). Scripts which work in Netscape browsers should include methods both for both Netscape 4.x and Netscape 6.x browsers.

Mozilla org: What have *YOU* done for web standards today? Mozilla new layout engine.
Are your JavaScript and CGIs ready for Nav5, IE5, and HTTP 1.1 CONTENT_TYPE? Get the latest info from Erick Krock.
Have a question? Before you email to him, first please check his answers.

It is easiest to create dynamic menus with some commercial applications. DHTML Menu Builder generates automatic necessary HTML-structures and CSS for different browsers. Older versions of the application create invalid CSS (most recent versions create standard CSS). If the CSS is not valid, menus work in some browsers only together with such HTML document types, when the browser don't work in the standard(-compliant) mode[S].

xFX JumpStart: DHTML Menu Builder.

If you know PHP, I have tried to create a model in order to update dynamic menus easily with PHP[S]. Menus, which I handle in this page are static HTML-code.

In this purpose is also free scripts. The original script, which I have used seems to be made by a quite new version of Macromedia Dreamweaver (according to an e-mail starting it is used starting from the version 4.01; the script is not in my sites in the original format). The usage of the main function (MM_showHideLayers(), the version 3.0) has been thought in many Web-sites, for example in TecsOfTheWeb.Com. Even if the script base on encoding of a commercial application, it can be freely used.

Macromedia, TecsOfTheWeb.Com: Using and Manipulating Dropdown Windows.

The site of the Finnish TV channel Nelonen (nelonen = four) use the same script as I have used in one level sub-menus. The site used however slow Java applets for Netscape 4.x. By giving as the keyword for search engines the name of the main function, it is possible to find much Web-sites, which use the same function, which I have used. As another example of good working dynamic menus in Opera (and presumably also in other new browsers) is also the site of Yomi Media (it use another JavaScript-encoding, but it use a resembling working system).

Nelonen, Yomi Media.

From the Internet can be found also other scripts, which work in Netscape 4.x and older MS IE browsers, but which don't work in Opera 4.x-6.x and Mozilla Gecko browsers (Opera 7.x supports the proprietary DHTML of MS IE, when at least a part of dynamic menus for old MS IE browsers work in that browser). Some versions of MS Frontpage creates scripts, which don't work in all DHTML/DOM supporting browsers. Scripts might be done also so, that they work in new MS IE and Netscape browsers, but not in older versions of MS IE and Netscape browsers. Below is an Web-address, which teach building dynamic menus, which work in most DOM1 supporting browsers (MS IE 5.x+ for Windows, Opera 4.x+ and quite new Mozilla Gecko browsers), but not in older MS IE and Netscape browsers.

CodeStyle: DOM1 Visibility menus.

Also MS IE 5.0 for Mac supports DOM1. Webreview writes about the support at the following way:

A good portion of DOM1 is supported in IE 5 for the Mac (chunks of DOM1 core are missing). However, the DOM support in Mac and Windows IE 5 is not consistent. This code is not cross-platform, and the Macintosh engine, while perhaps better at implementing DOM 1.0, is not consistent with IE 5 for Windows in all areas.

The advance of of the used script is that it works in all browsers, which overall support dynamic menus. The script has alternatives both according to proprietary DHTML and standard DOM working browsers. Advice, which I give in this page base on one ready made script (it is not necessary to change it at all).

Browsers have however problems, when it is difficult to find optimal solution. I give higher priority to newest browsers, if satisfactory solution for all browsers can't be found. In principle - but after hard work - it is possible with the used script to create in most browsers working nice "hand made" dynamic menus. For eldest DHTML supporting browsers might be reasonable to give static links. I explain in a separate page[S], how my own used dynamic menus work in different browsers.

If you use another code, dynamic changes must base on changing the value of the property visibility, because dynamic changes of the display property don't work in Opera. If you use the latter way, make sure, that users of Opera get at least so much links, that navigation is in overall possible without dynamic menus.

DHTML/DOM-menus can be in principle replaced with dynamic pseudo classes (:hover, :active and :focus) and IFRAME elements. I made some pages, which have experimental sub-menus[S]. In my tests systems work only in MS IE 5.5+ for Windows and Netscape 6.1+ (should work also in corresponding other Mozilla Gecko browsers), but not at all in any Opera browser (indeed works almost in Opera 7.0 Beta 1). Like DHTML/DOM menus IFRAME-based menus don't work in all browsers. That's why browsers should have the possibility to navigate the site also without the IFRAME-support. Because the functionality of this solution is very limited, I don't recommend anyone to use it. The only advance of this solution is that JavaScript support can be turned off. By using only CSS it is however possible to create only one level dynamic menus but DHTML/DOM menus can be as multi-level as necessary in individual cases.


Solutions for problematic situations

Because DHTML/DOM1 works at different level in browsers, in my mind DHTML/DOM-based menus should build so, that pages work also in such browsers, which don't support DHTML/ DOM scripts. Pages should work also in situations, where the user of the browser has turned off the JavaScript support. I have found situations, where without the JavaScript support doesn't exist at all working linking system. There is two reason for that matter. Either links have been generated "on fly" with JavaScript or they are hided (they have as default either visibility:hidden or display:none). I regard both solutions as bad. Links could be visible if the hiding would have done by using the onload attribute for the BODY-element. In this case links are visible if JavaScript has been turned off. This solution doesn't however work, because in dynamic menus links overlap the main content and maybe also total or partial each others.

In my mind following solutions are better:

  1. Main links work in all browsers and by using them it is possible to go to pages, which have continuation links. In this solution DHTML/DOM menus concern only sub-menus. In this case it is not relevant, if sub-menus have been automatic generated by scripts or they exist in the page, but scripts just hide/show them. It is not harmful, if a part of links are always hided, if the JavaScript support has been turned off.

    Browser-specific notes:

    1. It is not possible to solve all JavaScript and server problems, but if the presentation is not depending on the situations, if JavaScript support is enabled/disabled the visitor doesn't wonder, why the presentation changed quirky. At that mean this alternative is the most reasonable.

  2. Menu-related LINK elements are generated with JavaScript. At this way it is easy to tailor CSS for different browsers. Below is some examples of possible solutions:

    <script language="JavaScript" type="text/javascript">
    function linkStyle(sStyleFile,sStyleMedia)
    {document.writeln('\<lin'+'k\ rel=\"stylesheet\"\ type=\"text\/css\"\
    href=\"..\/Css\/'+sStyleFile+'\"\ media=\"'+sStyleMedia+'\"\ \/\>');}
    /* Shortening code by using a function. In later scripts the file name and the media type has been give as arguments of the function. */

    if (document.layers)
    /* This is a condition for Netscape 4.x browsers, which don't support DOM1, but which support proprietary DHTML. For Netscape 4.x browsers should not set several values for the attribute media (for example screen,print).*/

    else { /* CSS for other browsers. Netscape 4.x has difficulties with complex conditional statements. It is best to give for it the simplest possible conditions. */
    if (document.getElementById) /* This test, if the method which belongs to DOM1, is supported. This is a condition for all such browser, which support in the used script the DOM1 section (under Windows it is supported in MS IE 5.0+, Opera 4.x+, Netscape 6.x+ / corresponding Mozilla browsers). */
    {linkStyle("layers.css","screen,projection");} /* Opera needs the media type projection. Future PDA-browsers might need also handheld.*/

    else if (document.all)
    /* This is a condition for such MS IE browsers, which don't support DOM1, but which support proprietary DHTML. Because the used file is the same as in the previous condition, the condition could be combined with the previous test by using the format (document.getElementById) || (document.all). */

    else if (!(document.layers) && !(document.all) && !(document.getElementById)) {linkStyle("noLayers.css","screen");} /* For unknown browsers, which don't support either proprietary DHTML or standard DOM1. If they support CSS, they get static link tables without layers. In this case these conditions are unnecessary but this is an example of using excluding conditions. */

    else {} /* A formal termination of this block. This statement-block is not necessary but it is a good practise to end conditional statements a this way. */
    <script language="JavaScript" type="text/javascript">
    /* In this example most browsers have been detected on the base on browser-specific informations. */

    function linkStyle(sStyleFile,sStyleMedia)
    {document.writeln('\<lin'+'k\ rel=\"stylesheet\"\ type=\"text\/css\"\
    href=\"..\/Css\/'+sStyleFile+'\"\ media=\"'+sStyleMedia+'\"\ \/\>');}

    var IE4, OP, Gecko; /* It is a good practise to list global variables. */

    IE4 =(((navigator.userAgent.indexOf('MSIE')!=-1) || (navigator.userAgent.indexOf('Internet Explorer')!=-1)) && (navigator.userAgent.indexOf('Mozilla\/4.')!=-1)); /* Because newer MS browsers identify as Mozilla/4.0 compatible this detection fits also for newer versions. Some versions of MS IE use instead of the string MSIE the string Internet Explorer.*/
    OPua = (navigator.userAgent.indexOf('Opera')!=-1); /* Generic detection of Opera browsers. */
    op_pos=nua.indexOf('Opera'); /* Get the desired string. */
    /* At first has been defined, where to start counting digits after the desired string. The number 1 tells the quantity of used digits. In some identification strigs of Opera 5.x+ for Symbian OS (EPOC) browsers before the actual version number might be the letter v when the format (op_pos+7),1 is needed. */
    OP=(OPua && ((OPnu>=4) || (OPnu2>=5))); /* Detects Opera 4.x or newer browsers. In this case numeric values has been compared on the base of the previous variables (Opnu and Opnu2). Opera browsers can detect also by using detection strings like ((navigator.userAgent.indexOf('Opera 5')!=-1) || (navigator.userAgent.indexOf('Opera\/5')!=-1) || (navigator.userAgent.indexOf('Opera\/v5')!=-1) || (navigator.userAgent.indexOf('Opera v5')!=-1)). If for example Opera 5.12 for Windows would be in the mode Identify as Opera it would give the string Opera/5.12 and in other identification modes it would give the string Opera 5.12. Because dynamic menus work properly staring from 5.x+ it would be reasonable to ignore Opera 4.x browsers. */
    Gecko = (navigator.product == ('Gecko')); /* The detection for all Mozilla Gecko based browsers. It is possible to use also the same kind of detection method as for MS IE browsers above (navigator.userAgent.indexOf('Gecko')!=-1). */

    if (document.layers)
    /* CSS for the dynamic menus for Netscape 4.x browsers. Detecting Netscape 4.x browsers by creating variables from the identification strings doesn't work. */

    else {
    if (IE4||OP)
    /* The CSS for dynamic menus for MS IE 4.0+ and Opera 4.x+ browsers. */

    else if (Gecko)
    /* Total new or added CSS for Netscape 6.x+/ corresponding Mozilla browsers. The need of an own file is very small. If this section is not needed, the detection can be combined to the previous condition by writing it (IE4||OP||Gecko). */

    else {}

    <script language="JavaScript" type="text/javascript">
    /* A combination of method and browser based detections. You can support the widest possible range of unknown user agents if you test their feature availability. At least primary detections should base on supported methods. Only a part of the detection should base on the name of the browser or other browser-specific information. */

    function linkStyle(sStyleFile,sStyleMedia)
    {document.writeln('\<lin'+'k\ rel=\"stylesheet\"\ type=\"text\/css\"\
    href=\"..\/Css\/'+sStyleFile+'\"\ media=\"'+sStyleMedia+'\"\ \/\>');}

    if (document.getElementById){

    var OP, Gecko;
    OP =(navigator.userAgent.indexOf('Opera')!=-1);
    Gecko = (navigator.userAgent.indexOf('Gecko')!=-1);

    if (OP)

    else if (Gecko)


    else if (document.all)

    else {}


    Browser-specific notes:

    1. If it is necessary to detect the MS IE browsers more exact that in the previous examples, that can be done for example by using conditions like (navigator.userAgent.indexOf('MSIE 6')!=-1). Instead it is a bad idea to use the version number based detections, for example navigator.appVersion.indexOf("5.")>=0. In addition of the version number of the browser itself, it might mean also the version number of the compatible Mozilla, platform (for example Windows NT 5.0) or the version number of the deliverer of the browser (for example AOL 5.0). A possible identification string might be for example Mozilla/4.0 (compatible; MSIE 6.0; AOL 7.0; Windows NT 5.0).

    2. Some version of MS IE use exceptional version number strings, for example MSIE+5.5+. If version numbers have been test exceptional version number strings might remain unnoticed.

    3. MS IE for Mac and MS IE for Windows have not taken account separately. That can be done by adding conditions (navigator.userAgent.indexOf('Mac')!=-1) and (navigator.userAgent.indexOf('Win')!=-1). Don't use full names of platforms because some browser use for example identification strings Win32 and Mac_PPC.

    4. Opera browsers have many identification modes and they in most cases they partially "lie". In most case Opera works in the mode Identify as MSIE 5.0. Opera might get bad CSS or it doesn't get any CSS in solution, where has only been asked browser names and version numbers depending of course the way how browsers have been detected. The ways how I have detected in my examples Netscape 4.x and Netscape 6.x+ browsers don't concern Opera even it would be in a mode, where it pretends to be some Netscape browser. If detections are nested they might slower the performance.

    5. It is not possible to get the real version number of Opera by using for example navigator.appVersion.indexOf('5.')>=0 because Opera return just the version of the browser, which it pretends to be.

    6. Even if Opera would be in any identification mode, at least relative new versions can however always be identified as Opera, but this detection must be before other browser-specific detections or there must be additional conditions so that Opera would not read the incorrect CSS.

    7. I found that Opera 4.x is very sensitive that before spaces is a backslash (\) and after it just one space and no additional line breaks. Because of small error first detections, which I made failed. If line breaks makes the code clearer, the code must be catenated for example at the following way:

         'k\ rel=\"stylesheet\"\ type=\"text\/css\"\'+
         'href=\"..\/Css\/'+sStyleFile+'\"\ media=\"'+
         sStyleMedia+'\"\ \/\>');

    8. According to an e-email for Opera 3.x browsers is impossible reliable to give CSS, which is intended for browsers, which don't support DOM or proprietary DHTML because they don't always give the version number of the browser itself. I don't know, if this is true. At least Opera 3.62 for EPOC informs the version number.

    9. Concering mobile phones Symbian OS browsers use in their identification string as the platform the string EPOC. As far as I know Opera 5.x+ are the only browsers which support dynamic menus.

      Opera for Symbian: General Opera information.
    10. In the second, third and fourth alternatives Opera 4.x-5.x browsers might suffer. They don't read the JavaScript if the user has used backward/forward arrows (or other corresponding actions) of the browsers. If the visitor doesn't always select a new page they render links at the way, how other new browsers render links if the JavaScript support has been turned off. This disadvantage concerns however only few visitors.

    11. If Mozilla Gecko browsers are necessary to detect more exactly I recommend to use additional detections, which base on the Build ID of the browsers. They can be combined with the detections, which I have used in my examples. For example (Gecko && (parseInt(navigator.productSub)>=20011018)) concerns Netscape 6.1/ Mozilla 0.9.1 and newer browsers. You can separate Netcape from Mozilla by adding for example the condition condition navigator.vendor == ('Netscape7'). Then you can give different dates for Netscape browsers if it is necessary. In principle separations could also be done by using as exact version numbers as possible, for example userAgent.indexOf('Netscape6\/6.1'). I have a list of dates and some detection examples in the extra page, which concerns Netscape[S].

    12. You can use as a model a commented source code fragment[S], which I have used. You can also find more detection examples from pages of an e-mail friend of mine.

    13. In the Linux platform can be used also the Konqueror browser. As default it writes the name and the version number of the browsers and it uses an own rendering engine. Then it can be detected with it own name but an additional condition must be used (in the examples, which I have used it would be && !Gecko) because Konqueror can be set to use the Mozilla Gecko rendering engine. The user of the browser can however alter the identification string, when it is impossible to detect reliable Konqueror.

    14. When the purpose is to design forward-compatible detections it could be reasonable to eliminate effects of possible changes in the case of the sub-strings. Adding either toLowerCase(). or toUpperCase(). before indexOf changes in the case have no effects (for example toLowerCase().indexOf('win') works with both Windows and WINDOWS strings).

    15. I handle in another pages PHP-based[S] browser detections.

  3. All links are in the page, but elements, which define layers have been generated by scripts, when all links are visible, if the JavaScript support has been turner off. Below is an example of a generated start-tags (they needs also corresponding generated end-tag):

    <script language="JavaScript" type="text/javascript">
    if (document.layers)
    {document.writeln('\<lay'+'er\ id=\"Layer1\"\ class="\pageGroup\"\... \>');}

    else {document.writeln('\<di'+'v\ id=\"Layer1\"\ class="\pageGroup\"\... \>');}

  4. It is possible to make a combination of two previous alternatives. In this solution in the main CSS-file is almost all needed CSS including most of the layer-related CSS. Only very little is in the CSS-file especially for dynamic menus. Even if the browser doesn't read the CSS file for dynamic menus, dynamic menus could work at least partial if just the browser can generate the necessary elements.

  5. In the menu is in a clear place a link to a special link page, which has continuation links into all necessary pages. It is not necessary that the actual menu is as default visible. There can be instead of the menu a link to the special link page, which can be for example a big link table.

  6. In situations, where JavaScript support has been turned off, the browser gets an alternative link set. The basic CSS-file ends in situation, where dynamic menus will be hided and the browser reveals alternative links. Below is an example of this solution:

    /* The following CSS is in the end of the basicScreen.css file: */
    #alternativeLinkSet {display:block;} /* Links for the alternative navigation. */
    #tableAllPages {display:none} /* Links for dynamic menus. */

    /* The following CSS is the beginning of the layers.css: */
    #tableAllPages {display:block}
    #alternativeLinkSet {display:none}

    Browser-specific notes:

    1. If the CSS commands to changes property values and much CSS has been given in two big CSS-files, the situation however "stress" browsers. I found in a test, where browsers had alternative link set in situations, where the JavaScript has been turned off in MS IE 5.0 for Windows the page must reload to get dynamic menus. This might be related on CSS (and/or servers), but not necessary because the CSS was partially depend with JavaScript supports. One way might be to generate CSS for hiding the alternative link set/ link set of revealing dynamic menus CSS with JavaScript like in the example below, but the following system doesn't necessary solve the problem:

      <script language="JavaScript" type="text/javascript">
      {document.writeln('\<sty'+'le\ type=\"text\/css\"\>');

    2. That previous solution doesn't solve another problem, which concerns alternative links. The another weakness of alternative links is that if the JavaScript support have been disabled Netscape 4.x shows both links for the dynamic menus and alternative links because taking off the JavaScript support takes off also the CSS-support. Also such browsers, which don't support at all CSS get two link sets.

In all ways to give different CSS for situations, where JavaScript support is enabled/ disabled have some problems, which might be related on servers, JavaScript handling or CSS-handing. If the server must gather CSS from several pieces, the browser might not get it enough fast, the browser might render the page incorrectly. If connections work well, CSS doesn't cause problems.


Used JavaScript encoding


Model files

In DHTML/DOM menus the JavaScript encoding is related with CSS and HTML encoding. The system needs one JavaScript and few CSS files, encodings to head section and event handlers to the body sections of the document. Following example files (I have used them in my Finnish and English CSS-pages) can be freely used designing dynamic menus:

Generic notes:.


Links of the dynamic menus can exist in the page or they can be generated by JavaScript encoding or some server-side systems. In the example pages links are inside tables. The JavaScript, which I have used just controls which menus will be revealed/ hided and how they will be revealed/ hided.

The main principle of dynamic menus is very simple. The author defines blocks, which work as dynamic menus. He sets for them id-attributes, which correspond values, parameters (they are called also as arguments) in the even handlers. The most used event handlers are onmouseover, onmouseout and onclick (the last can be replaced with href="javascript:" in situation, where normal links are not needed). I teach using of them. Functions, which Web-authors should detect when he designs dynamic menus are just three:


Timered menus

The author must then just select, how menus should work in each levels. Below is an edited screen capture from the English example page[S]:


How to design dynamic menus have timer functions and the menu use the following system (the explanation has shortened source code examples):

  1. From the main menus the visitor can go the the second level links by moving the mouse over the link and then moving the mouse to the right (if the visitor clicks the link he goes to the first page of the selected page group) or clicking links in the arrows (). Selecting one sub-menu closes other second level menus:

    <a href="index2.php3#Full" onmouseover="ajastin_pois(); MM_showHideLayers('indexPages','','hide','allSites','','hide','Generic','','show',...);" title="">Generic</a>
    <a href="javascript:ajastin_pois(); MM_showHideLayers('indexPages','','hide','allSites','','hide',...);" title="..."> <img src="..." title="..." alt="..."/></a>
  2. Going out from the second level menus they disappear from the screen after few seconds with a timer. It is possible to go from the second-level to the third-level at the same way as from first-level to second-level. Below is the source code, which keeps the second level menu visible and close it after going out of the menu:

    <div id="Generic" class="pageGroup" onmouseover="ajastin_pois(); MM_showHideLayers('Generic','','show');" onmouseout="piilota_valikot_hitaasti('Generic');">
  3. The third-level menu keeps the second-level menu visible. The third level menu can be closed fast when the visitor goes out of the menu:

    <div id="Generic1" class="pageGroup" onmouseover="ajastin_pois(); MM_showHideLayers('Generic','','show','Generic1','','show');" onmouseout="MM_showHideLayers('Generic','','show'); piilota_valikot_nopeimmin('Generic1');">

In the previos explained solution has quite many generic and browser-depending JavaScript-related problems.

Generic notes:

  1. Commands for the container elements have higher priority than commands for individual links - links inside the container element can't change show/ hide commands, if the commands concern the same element(s)!

  2. The previous explained system has problems with closing in some situations third-level menus, if the visitor moves the mouse to the left and ever goes to the menu itself.


    If there is no links on the left, the third-level menu might remains visible until the visitor goes to the main menu. In the meantime the third-level menu leaves as an "orphan" on the screen. The problem could be partially solved by adding to the left of the opening link of the third-level menu a transparent image or some non-breaking spaces (&nbsp;), which (normally) close the opened third-level sub-menu. Below is an example of an imaginary filling image (so-called spacer images, which are usually transparent GIF-images):

    <a class="filling" href="#" onmouseover="ajastin_pois(); MM_showHideLayers('AppendixesStandards','','hide');"> <img src="../Images/spacer.gif" width="11" height="15" /></a>

    These kinds of tricks are in my mind irritating artificial. They have the problem that fast movements of the mouse might leave third-level menus visible, because active areas are very small. The browser has just not enough time to react to the events.

  3. Additional active spacer images are needed also in situations, where the lowest links of menus open a sub-menu. In these situations the invisible links close the last opened sub-menu.

  4. If function calls become too big to keep track, they can be gathered as new functions, for example (this is in the Finnish example page):

    function hideThlMenus() /* Hide all third-level menus */
    {ajastin_pois(); MM_showHideLayers('GenericPreface','','hide',...);}
  5. I have found that slow reacting speeds of browsers is a generic problem. That's why I have added some such closing commands to the main menus, which should in principle be needed only in the second-level menus.

Browser-specific notes:

  1. Especially in Opera 5.x-6.x and sometimes also in MS IE second level menus might disappear unexpected if the visitor scrolls menu items upward and downward without clicking anything. In Opera 7.0 Beta1 doesn't have stability problems with timered menus.. Menus are even more stable than in MS IE browsers.

  2. Opera 5.x-6.x don't keep in this solution second-level menus reliable open, when the visitor is in some third-level sub-menu. The visitor must whole time move his mouse. If Opera have hided the second-level menu, moving of the mouse pointer can again get visible the hided second-level menu. The user of the whole menu system feels quite unstable even if the stability problem is not serious.

  3. If in the third-level menu in the state onmouseout have been not been use a timer but instead onmouseout="MM_showHideLayers(...,'Generic1','','hide');" it is not possible to go the third-level menu at all with Netscape 6.1 level Mozilla 0.9!

  4. If for example the third level menu AppendixesStandards will be closed from the second-level menu with MM_showHideLayers('AppendixesStandards','','hide'); the result is that with MS IE 4.x for Windows browsers it not possible to go to the third-level menu at all, because the browser support buggy onmouseout for container elements (onmouseout affects the result in areas, which are not links even if the behavior should be dependent on the edges of the container element). If the closing has been done with the timer function piilota_valikot_nopeasti('AppendixesStandards'); Opera 5.x-6.x have problems with it, because it cause in Opera unexpected closing of menus! In my mind following commands for the second-level menus are not very useful:

    <div id="Appendixes" class="pageGroup" onmouseover="ajastin_pois(); MM_showHideLayers('Appendixes','','show');" onmouseout="piilota_valikot_hitaimmin('Appendixes'); MM_showHideLayers('AppendixesStandards','','hide');" >
    <div id="Appendixes" class="pageGroup" onmouseover="ajastin_pois(); MM_showHideLayers('Appendixes','','show');" onmouseout="piilota_valikot_hitaimmin('Appendixes'); piilota_valikot_nopeasti('AppendixesStandards');" >
  5. Browsers work better if the timer has not set direct to the links (the A elements) but instead in the container block, in the ancestor element (possible padding areas are active, but borders and margins don't belong to the active area of the container element). Timers for individual links cause flickering, links disappear unexpected and they can't be opened immediately - in overall the accessibility is in general bad! Especially Opera 5.x-6.x have problems. The same problems are also in MS IE for Windows browsers, but not as a bad as in Opera 5.x-6.x. I found that closing links with the container element don't however always work in Opera 5.x-6.x as expected if timer functions has been used (Opera might close menus unexpected).

  6. In Netscape 4.x browsers container element of links work at the previous mentioned way only by using LAYER or ILAYER elements. This one of the two reasons, why I use LAYER elements. I must use them also because used CSS didn't work in all situations in Netscape browsers together with DIV elements and JavaScript-encoding as it does in other DHTML/ DOM capable browsers. It is however possible to get JavaScript to work together with LAYER elements. I had difficulties to get JavaScript to work with the first LAYER. I took off position-related CSS from the corresponding DIV element (other browsers get it linked). I used in certain evaluation versions formal empty "menus" (<div id="foo" style="visibility:hidden"></div>), which I don't anymore need. In random situations I need to generate an additional LAYER in order to get the first menu-related element to work properly. I got finally every desired menu to work with LAYER elements. I have generated them with following kinds of scripts:

    <script language="JavaScript" type="text/javascript">
    if (document.layers)
    {document.writeln('\<lay'+'er\ width=\"120\"\ visibility=\"hidden"\ top=\"66\"\ left=\"141\"\ id=\"MainPages\"\ bgcolor=\"white\"\ onmouseover=\"ajastin_pois(); MM_showHideLayers(\'MainPages\',\'\',\'show\');\"\ onmouseout=\"piilota_valikot_hitaasti(\'MainPages\');\"\>');}

  7. According to an e-mail onmouseover event handler attributes didn't always work in MS IE 5.0 for Mac browsers in some evaluation version of my dynamic menus. Because of this reason in some pages only javascript:... commands opened sub-menus. If possible dynamic menus should be tested also in MS IE 5.0 for Mac browsers. According to my experience the same kind of problems are also in Opera 4.x browsers, but it is not necessary to take account Opera 4.x browsers.


Non-timered menus

As it has been obvious in my mind in the previous mentioned example "solution" which use timer functions has too much serious problems, which are related with the stability and closing of sub-menus. It is however possible to get rid of them. Following solutions work better:

  1. Menus have special closing links.

  2. Menus have hided closing links in necessary sides of the menus.

  3. Menus have closing link in the actual content of the page (in this solution dynamic menus should not be inside the actual content). The closing function should not have a timer because Opera 5.x-6.x works well only if the timer has not been used. Browsers might have small delay times before they close open menus. This is however quite harmless delay because browsers always close menus when the visitor moves his mouse.

In the previous list first and second spots are however unnecessary. For most browser the most reliable working system is the following:

A background box

Shadow boxes

If the purpose is that dynamic menus will be opened and closed automatic with onmouseover attributes they are the only possible ways, how menus work as reliable as possible in MS IE 5.x+ (Mac and Windows), Opera 5.x+ and Mozilla Gecko browsers. Especially my solution improve the performance of dynamic menus in Opera 5.x-6.x browsers if multi-level sub-menus have been used. I must however point out that menus work in all previous mentioned browsers as flawless as they can ever work. Also user of MS IE can be fully satisfied in my solution. In my mind (at least) three-level dynamic sub-menus work well if the menu system fulfil following requirements (my system fulfils all of them at least with some variations):

  1. All sub-menus are absolute stable in all circumstances. For example when the user is in some third-level menu the second-level menu, which works as the "parent menu" (the menu, which opens the next level menu) remains stable visible.

  2. Sub-menus will never close unexpected (all situations, when the menu will be closed, when the visitor is inside the menu block are unexpected situations; also situations where the visitor scroll menu items and the menu disappears is an unexpected situation).

  3. Sub-menus never will be close before the visitor has passed the whole menu block.

  4. The visited sub-menu will be closed when the visitor goes out of the whole menu block except situations, where the mouse is in a position, which opens a next level sub-menu.

  5. The parent menu is visible the whole time, when the visitor is in the last opened menu level.

  6. There are no situation, where a sub-menu could leave as "orphan" (for example a third-level menu is orphan in a situation, where the third-level menu is visible but the second-level parent menu is hidden).

  7. When the visitor has gone to any last level sub-menu he can go from that sub-menus to the same path back to the first-level main menu.

Special advances of my solution are following (many of them are impossible to solve with other kinds of solutions):

  1. In my solution is never serious problems, which timer delays might cause.

  2. Artificial spacer images are not needed at all.

  3. Special closing links are unnecessary.

  4. The quantity of event handler attributes can be minimized and onmouseout is not necessary needed at all in closing commands of sub-menus.

  5. Menus can be quite multi-level without remarkable problems. I have used four-level sub-menus and they have been worked as flawless as second-level sub-menus.

  6. This is extremely easy solution for Web-authors (authors must however know, which browsers support it).

  7. If the author leaves enough empty space around links (and/or menus have background boxes), the user of menus don't by accident close menus and fast closing menus feels quite comfortable to use.

The restrictions and disadvantes of this solution are following:

  1. The only remarkable restriction is that smooth "comfortable" delay times are not used. Users of Windows XP might have used them (personally I don't like slow and smoothly opening drop-down menus). Browsers must however work in the Internet in much more unstable environment that ordinary application under stable platform. It not reasonable to ask for a Web-page the same "comfort" as for example MS Word. Indeed delay times are more harmful for some browser than for some other browser. If author (like many author in fact do) don't care more or less impaired functionality in some browsers, timer functions can be used.

  2. Menus can't be designed so that when the visitor goes outside the last level sub-menu only the last level sub-menu disappears but previous level sub-menus remains always visible. In generally visitors don't want this kind behavior because if the last level menu would leave always previous level menus visible, the visitor should always especially close previous level menus. It would cause extra work for the visitor, which is in generally regarded as an unpleasant feature. In my system it is always the possibility to go back along the same path to the main menu but "slipping" from the path closes all opened sub-menus. Indeed as needed it is possible to avoid slipping by using background boxes.

  3. As a small disadvantage of my solution is the fact that the best possible solution for MS IE 4.x for Windows Web browser needs defining much shadow boxes. Shadow boxes have however some advances also for other browsers but doing them only because of MS IE for Windows is questionable. MS IE 4.x for Windows has become quite little used browser and the meaning of this disadvantage lessens day by day.

Browser-specific notes:

  1. If the structures of the dynamic menus are very heavy I have found that going from third-level menu to second-level menu MS IE 6.0 for Windows (concerns presumably also the 5.x series) might close menus unexpected if the whole content close the menu by the onmouseover or onmousemove attributes in situations. I found that I didn't have defined the z-index property for the base element of the dynamic menus and the main content. When I set the functionality improved but the problem didn't disappeared totally.

    I got that problem solved only by defining an active background box behind the entire menu. It is reasonable to set for the background box either the onmouseover or the onmousedown attribute because onmouseout attribute close menus when the visitor goes first out of the whole menu and then tries to return back to a sub-menu, which is inside the background box. If the background box has a background color there is no problems between the closing commands of the background box and the actual content. A transparent background box worked worse. In my tests onmousedown for the colored background box and onmouseover for the content worked ok. If the background box used onmouseover the content should have either onmousedown or onclick attributes. In problematic situations it is reasonable not to use at all closing menus through the actual content or closing menus trough the content has been designed so that it doesn't concern MS IE 6.0 for Windows. If sub-menus have shadow boxes closing through the content doesn't cause problems.

  2. MS IE 4.x for Windows closing menus with onmouseover or onmousemove or attributes from elements, which are directly below the menu cause the problem, that sub-menus don't always stay open and menus are extremely unstable. I tried onmousedown but links were difficult to open and it doesn't work as it should. Only the onclick attribute can be used in this purpose. If this browser is intended to support, closing sub-menus through the content should be implement conditional by using the document.write() method of JavaScript so that the closing dynamic menus from the content by using certain event handler attributes doesn't concern MS IE 4.x for Windows. Sub-menus might remain open but this is much better situation than the situation, where it is not possible to select some menu items in the desired sub-menus.

    In the example code below the task of the function hideAllGroups() is to close all opened sub-menus through the actual content of the Web-page. Adding the following code before the actual content of the document force all dynamic menus supporting browser at least with some event handler to close all opened sub-menus (all of these even handler are not necessary to set):

    <script language="JavaScript" type="text/javascript">
    if (document.getElementById)
     onmouseover=\"hideAllGroups(); \"\>');}
    else if (document.layers)
    {document.write('\<layer\ z-index=\"0\"\ 
    else if (document.all)
    else {}
    The actual content starts here...

    If behind the menu have been set a background element and/or each sub-menus have their own shadow boxes, which don't have event handler attributes, which concerns the previous mentioned browser, menus can be closed from the actual content with any supported event handle attribute because the content is not directly below the menu. The background element and/or shadow boxes work then as an "insulations" between the menu and the main content.

  3. If shadows are positioned on the base of the absolute positioned element, Opera 5.x might not position them correctly. Use browser-specific CSS for Opera 5.x or don't use nested postioning.

  4. As I have earlier explained all structural solutions don't work in MS IE 5.0 for Mac browsers, why it would be reasonable to use as simple solutions as possible (you can go through a test case[S] MS IE 5.0 for Mac browsers).

  5. Closing menus from the content needs in Netscape 4.x browsers that the whole actual content is inside LAYER or ILAYER elements.

If you want more advice, I recommend to visit in other sites. You can find good hints also from the site of TechsOfTheWeb.

TecsOfTheWeb.Com: Using and Manipulating Dropdown Windows.




Visibility & position

In all other browsers than Netscape 4.x the positioning base on CSS and In all DOM/DHTML capable browsers properly supported properties and property values are position:absolute, top and left. In addition of these authors must define the stacking order with the z-index property, where higher value means higher position in the stack. The default visibility value for dynamic menus is in general for the main menu visibility:visible and for sub-menus visibility:hidden. These values will be altered with JavaScript.

If menus are intended to close through the content both for the base element and the actual content should be set the z-index property in order to get stacking order relative to the whole Web-page. If the base element of menus doesn't have the stacking order any following element in the content, which has the z-index property should set above the menu. Stacking order values for elements inside the base element of menus remain internal.

At this way positioned element don't affect anything to the positioning of other elements. For example the effect of position:absolute; top:50px; left:50px; width:600px; height:400px; visibility:hidden is in practise the same as if for the element has been set display:none. Hided and positioned links don't take any space of the other content of the document.

The system, which I have explained can be used in all situations, when elements can beforehand set exact positions. The most typical solution is a drop-down-menu, which I have handled in this Web-page. The advance of this solution is that opening of menus newer cause need of redraw the whole document or most of it. In my solutions only defined menus will be revealed in the positions, where they really are in the page! Even if menus will be generated "on fly" they will not affect anything to the positions of other elements in the page - only the speed and/or reliability is different compared to links, which already exist in the page.

Because I have from the same basic menu several versions I collected groups according to the horizontal or vertical positions of menus (the names of menus and values of properties are today different as in the example):

/* horizontal positions and x-index for second level sub-menus */
#Generic, #MainPages,... {left:128px; z-index:19;}
/* horizontal positions and the z-index for third level sub-menus */
#MainPages, #Appendixes, #Generic1,... {left:266px; z-index:20}
/* vertical positions for all menus */
#Pages, #PagesEn,... {top:42px}
#MainPages, #Generic1,... {top:59px}

I have used in my examles multi-level sub-menus. Instead of multi-level sub-menus it would be possible to use indented links for lower level pages - compare alternatives with two screen capture images[S].

Browser-specific notes:

  1. MS IE renders elements, which have visibility:visible as visible even if they are inside elements, which have visibility:hidden. This is the correct behavior. Opera hides always and new Mozilla Gecko (for example Netscape 6.1) browsers if position:fixed has been used hide incorrectly these kinds of elements (a test page[S]).

  2. In first dynamic menus previous mentioned properties didn't always worked in these Netscape 4.x browsers, which I have tested. That's why I have in all cases given in the example pages corresponding attributes for LAYER elements. The LAYER element doesn't have the position attribute but in the previous example <LAYER top="66" left="141"> means in theory the same as position:absolute; top:66px; left:141px in CSS (and for example z-index="3" means the same as z-index:3) - indeed Netscape positions elements a little bit differently as MS IE and Opera. Because LAYER elements are proprietary I use them only generated by scripts.

  3. I recommend to read my generic advice[S], when it is possible to avoid big problems.

In the most advanced browsers could be used also the position:fixed positioning type. This way positioned menus are accessible in all situations. Using position:fixed cause on remarkable limitation to the designing because the only reasonable system is that the main menu is vertical. Menu items are under each other. If a wide horizontal main menu is used all anchors cause problems because the menu hides the beginning of the content. The visitor should scroll page always a little bit upward when internal links have used - he would be soon as an angry wasp and he would swear very much!

If there might be a situation, that the menu could hide some content, it should be the possibility to hide the whole menu[Pw]. Of course there should be also a link to show the hided menu again. Below are some images, which could be used to hide and the main menu. They are on the left side of the screen capture of a dynamic menu, which use them.

Nature pages

Hiding and showing menus could also set as full or half-automatic. In the latter case onmousedown for the main content should close the whole menu. It would reveal then on the (left, right of both) sides of the page active areas, which have onmouseover to reveal the menu again.

Browser-specific notes:

  1. It can be defined with attribute selectors, when MS IE doesn't understand it but it would work in new Opera and Mozilla Gecko browsers:

    div.pageGroup, div#allPages {position:absolute} div[class="pageGroup"], div[id="allPages"] {position:fixed !important}/* Because attribute selectors have lower weight than id-selectors, in the the declaration must use the !important rule. */
  2. The system doesn't work ideal in Opera 5.x-6x (works properly starting from Opera 7.0 Beta 2) and not at all in MS IE 5.0 for Mac. It works ideal only in new Mozilla Gecko browsers (read about deficiencies closer from the page, where I handle the functionality of browsers[S] in my sites; I made also a test case[S] in order to demonstrate problems)

  3. Instead of fixed positioned elements is is possible to use with JavaScript-encoding implemented elements, which "float" with some delay to their positions. The functionality is worse than fixed positioned elements. I handle these kinds of elements in an extra page[S].
  4. Even if Netscape 6.0 doesn't support the position:fixed type I found that it works according to the position:absolute, when this solution didn't cause those problems with Netscape 6.0, which I expected.

  5. I have sometimes seen elements, which stayed in their positions. Because browsers moved elements upward/downward the functionality was not very good. I can't teach scripts, which implements (at least partially) fixed elements. Below is a Web-address to the menu Top Navigational Bar IV (ver. 3.3.19) by Andy Woolley. That menu works with certain setting stable in most browsers (including Opera 5.x-6.x) and it follows scrolling (with default preferences the menu in unstable in Opera 5.x-6.x and Opera 5.x has difficulties to download the JavaScript).

    Setting in the script menu_arrays.js for the menus for example ,,120,1,,style1,0,"left",effect,1,,1,,,,,,,,,, menus stay visible and they follow the scrolling until another sub-menu has been selected. In multi-level menus the behavior is in most browsers quite bad because sub-menus follow the parent menus with irritating delays. The functionality is much worse than position:fixed in Mozilla Gecko browsers. The most reasonable usage for this kinds of links is few link arrows, which go to the top of the page (a model page[S]) and previous/next page. Indeed with Opera 7.x also multilevel menus in the Milonic Web-site of Andy Woolley work quite well (much better than in MS IE 6.0 for Windows) and Opera 6.x (the menus doesn't however start working as soon as in Opera 7.x). That site use an updated version of the previous mentioned menu (the version, which I downloaded was 3.5.08 but today it is presumably newer). Opera 5.x can't always download the version 3.5.08 and if Opera can download it, ver. 3.5.08 doesn't fit for Opera 5.x. In order to solve this problem it necessary to write a script so that Opera 5.x gets the older version (look at the source code[S] of this page). In general the basic problem of these kinds of menus is that menus are available only if the JavaScript support is enabled. It would be a better solution to build the basic structure of menus by using server-side programming, when the menu would be at least at some level available also in situations, where the JavaScript support has been disabled. Try to create dynamic menus with PHP[S].

  6. The problem that menus might be over the content could in principle ease also by setting the transparency with the opacity property, which belongs to CSS3. With Netscape 6.2+/ Mozilla 0.9.4+/ at least as new other Mozilla Gecko browsers can use the -moz-opacity property, which is a temporary implementation of the opacity property.

  7. With Opera could test also other positioning types than top-left, but the functionality is in other browsers is weak. I don't recommend to use bottom-left, top-right and bottom-right positioning types. Individual links or small link sets can be positioned according to them but not dynamic menus.


Other alternatives

If menus will be defined in the same place and the same size, in principle they can be implemented instead of changing the values of the visibility property with the changes of the values of the z-index property. I don't however how wide this alternative works.

The weakness of both visibility and z-index based solutions is, that they don't fit for menus, where the position of elements can't set beforehand. An example of these kinds of menus is the Explorer of Windows, which I have a screen capture below.


Because the menu can be expanded in any situation, the vertical positioning can't be defined beforehand. Elements should be able to hide/ reveal by changing between display:none and display:block. If elements have display:none they behave as if they don't exist at all in the page. When they have display:block they clear space for themselves.

This solution has a great disadvantage if for the menus has not been reserved at all or for them has been reserved insufficiently space to expand. Opening of menus can cause continuous need to reformat the document. This slow down the performance of the browser and it might crash it. As I have written changes of the display property don't work in Opera 4.x-6.x browsers. If I have understood correctly, because of previous mentioned reasons Opera Software has been decided, that Opera 4.x-6.x browsers don't accept dynamic changes of the display property. In my mind changing of the display property in frame free Web-sites is overall a bad solution even if Opera 7.x+ and other modern browsers support them.

Menus, which resemble the Explorer fits in my mind only into frame documents, where the menu is in its own frame - also the Explorer works in this principle! The corresponding system can be achieved with Java applets, for example with products of Auscomp. The disadvantage of Java applets is that they are slow and many browsers don't support them as default. The JRE of Sun Microsystems is a big plug-ins application in order to download with modem connections! It is possible to create dynamic menus also as Flash-animations. In addition of products of Macromedia it is possible to create them also with other application. I have no experience creating dynamic menus with them.

Auscomp, Macromedia, Sun Microsystems.

Advantages and disadvantages of Flash- and applet menus:

Menus are relative easy to implement inside frames also by creating "on fly" with JavaScript of server-side encoding a total new menu page, when the visitor has been clicked a link of a sub-menu. These kinds of menus work also in Opera.



Concerning the presentation problems continues with the Netscape 4.x series because CSS works just partial in the dynamic menus, which I have used. Browsers have especially difficulties with linked CSS, because just a part of it works. Because direct CSS works better, I have used some style attributes (if necessary I have cancelled the effects by using the !important-rule in the CSS for other browsers). I must add some extra elements (for example B and IMG) in order to get the presentation better. Links seem to need the FONT element, because even the style attribute doesn't always work. For other browsers than Netscape 4.x I have defined the presentation primary through external CSS-files.

If Netscape 4.x series browsers should be supported, the HTML-code for dynamic menus must be in the beginning of the page because I found that Netscape 4.x crashed when the code was in the middle of the page inside a table!

In my mind it is reasonable to set id or class attribute for each individual link or the container element of each links. At this way is possible to get the same menu to look different in every page. Each page has a style sheet, which defines the style of the link, which refers to the current page. In one level dynamic or static menus the link to the current page can be hided with display:none or for it have been set special color and/or background-color/ background properties. The latter alternative can be used also in multilevel dynamic menus. For Example this page has the following CSS:

#Dy {background-color:#ffd700 !important; color:#303400 !important; cursor:default}

It cause the following result (in order to get good result as many browser as possible the definition should be given both to the link itself and the container table cell, if the link is inside a table; remember that the value of the id-attribute should be document wide unique):


Properties have !important in order to eliminate changes of link and dynamic pseudo-classes (a:visited ect). If links don't have any sub-menus they can have cursor:default. By marking the current page the visitor doesn't click so easily the link of the current page. He can also clearer know, where he is in the selected page group.

New Opera, MS IE and Mozilla Gecko (for example in Netscape 6.x) browsers don't need image links because setting for the link display:block a normal text link looks like an image as in the screen capture image below (in new Opera and Netscape the whole element works always as a link but in MS IE the whole element is in some cases active and some cases not; in the latter case display:block cause just the visual effect but only the the text works as the link; if in MS IE the width property has other value than auto links are active at the whole available width except in situations, where links use the property float and links don't fit to the same line; it is also possible to get rid of this problems by the method, which I have intended primary for MS IE 4.x for Windows).


By using some pseudo-classes it is possible to get the same result as with JavaScript & event handlers, which change images or background colors of text links, when the mouse goes over/out of links or it does some other actions. In order to get the optimal result links need for example following properties:

.pageGroup a {display:block; width:100px; height:15px; line-height:15px; margin-top:0; margin-bottom:0; padding-top:0; padding-bottom:0 font-size:12px} /* Without the line-height property there might leave vertical space between links and text links don't behave exactly like image links. If links are inside table cells, also table cells need the line-height property in order to get good result also in Mozilla Gecko browsers (further is into this matter related code example). It is reasonable to set padding and margin properties should be set as zero in order to get links work equal in as many browsers as possible. The font size would be desirable to set so, that is possible to zoom it 120%. */
.pageGroup {background:...; padding-left:11px;...} /* I have used in some versions around text links elements, which I gave background properties and the padding-left property. This element layer is not necessary. I recommend to set only background colors because background images don't work in all browsers. */
.pageGroup span.Link a:link {background:...; color:...}
.pageGroup span.Link a:visited {background:...; color:...}
.pageGroup span.Link a:hover {background:...; color:...}
.pageGroup span.Link a:active {background:...; color:...}
.pageGroup span.Link a:focus {background:...; color:...}

Because display:block doesn't work properly in Netscape 4.x and MS IE 4.x for Windows browsers, the solution doesn't look out smart in MS IE 4.x for Windows and Netscape browsers (look at a screen capture from the implementation of MS IE 4.x for Windows above on the right and compare it to the image on the left). It is however possible by using media blocks to define CSS so, that MS IE 4.x for Windows and Netscape 4.x don't get background properties for text links (I have advice in the extra page, which handles MS IE problems[S]; I use however background colors for text links, which gives sometimes a little bit bad looking result in these browsers).

Indeed for MS IE 4.x for Windows is possible to create the same result with event handler attributes for container elements of links. If all opening and closing commands have been executed by using the container elements of links, it would be possible to give the illusion, that links are active at their whole available widths, for example::

var nav_over = "'#cee8ea';";
var nav_out = "'#ffffff';";
<div onmouseover="MM_showHideLayers('Generic','','show',...); eval(nav_over);" onmouseout="eval(nav_out);"><a onmouseover="MM_showHideLayers('Generic','','show',...);" href="..."></div>

Adding corresponding functionality for Netscape 4.x browsers increase drastic the quantity of necessary encoding because it is necessary to add (9nce again) LAYER elements.

Text based links could work relative well in Netscape 4.x and MS IE 4.x for Windows browsers, if links itself would not have background properties and each link would be in an own table row so, that both on the left and on the right would be a table cell and widths of the cells, which has the text links would have been defined with spacer images. In the cells on the right and left would be opening/closing links of sub-menus. On the cells on the left would be list bullets. If necessary height values have been defined by using spacer images. I changed my menus using this style in order to demonstrate the system.

Indeed it still exists a problem, which concerns borders. If borders have been set with CSS Netscape 4.x leaves between the background color and the borders of the container block few pixel wide ugly transparent padding. In addition eldest Netscape 4.x series browsers crash easily, when CSS-borders have been used. Taking account all matters, the best solution to avoid this problem is to set the background color for the entire table and set "borders" by using table cells around the the content (cells can use rowspan and colspan attributes). I don't have created these additional cells to all menus, but only for the main menus.

Another way to avoid transparent paddings is to set background colors for LAYER elements and the descendant block has the borders. Below is a screen capture from a test menu. In the first level menu I have solved background color and border problems with additional table cells. In the second-level menu I have used a generated LAYER element.

A test page

The advance of the LAYER solution is that is is simple and also background images work so, that Netscape 4.x doesn't splitter them ugly way into individual table cells. But it has also disadvantages. From the screen capture can be seen, that the height of table rows are not the the same. Around the right hand table is a block, which has border and padding properties. In these kinds of situations the height of the tables vary even if they would have equal quantity of rows. The advance of additional cells is that vertical dimensions work more exact. In fact exact working paddings areas need around the content additional table cells at the same way as borders (the quantity of needed columns is then seven and additional table rows four).

In the example document[S] has been used have seven columns but in sub-menus simpler three columns structures. All menus and related link sets on the top-left are inside LAYER elements, which are generated by scripts. Below is the method how to create additional table cells and columns (because the natural dimensions of the spacer image is 1x1 pixel, it is not always necessary to set both height and width attributes):

<table summary="" cellspacing="0" cellpadding="0" border="0" bgcolor="white" width="126" >
<tr class="topCells">
<td id="cell1" bgcolor="#303400"><img src="spacer.gif" border="0" alt="" height="1" width="1" /></td>
<td id="cell2" bgcolor="#303400"><img src="spacer.gif" border="0" alt="" height="1" width="2" /></td>
<td id="cell3" bgcolor="#303400"><img src="spacer.gif" border="0" alt="" height="1" width="11" /></td>
<td id="cell4" bgcolor="#303400"><img src="spacer.gif" border="0" alt="" height="1" width="101" /></td>
<td id="cell5" bgcolor="#303400"><img src="spacer.gif" border="0" alt="" height="1" width="8" /></td>
<td id="cell6" bgcolor="#303400"><img src="spacer.gif" border="0" alt="" height="1" width="2" /></td>
<td id="cell7" bgcolor="#303400"><img src="spacer.gif" border="0" alt="" height="1" width="1" /></td>

<tr class="paddingCells">
<td rowspan="5" bgcolor="#303400"><img src="spacer.gif" border="0" alt="" width="1" /></td>
<td rowspan="5"><img src="spacer.gif" border="0" alt="" width="2" /></td>
<td colspan="3"><img src="spacer.gif" border="0" alt="" height="5" /></td>
<td rowspan="5"><img src="spacer.gif" border="0" alt="" width="2" /></td>
<td rowspan="5" bgcolor="#303400"><img src="spacer.gif" border="0" alt="" width="1" /></td>

<tr class="contentCells">
<td><img src="menuButton.gif" border="0" alt="" height="10" width="10" /></td>
<td>The first row</td>
<td><img src="rightArrowr.gif" border="0" alt="" height="15" width="8" /></td>

<td><img src="menuButton.gif" border="0" alt="" height="10" width="10" /></td>
<td>The second row</td>
<td><img src="rightArrowr.gif" border="0" alt="" height="15" width="8" /></td>

<td><img src="menuButton.gif" border="0" alt="" height="10" width="10" /></td>
<td>The third row</td>
<td><img src="rightArrowr.gif" border="0" alt="" height="15" width="8" /></td>

<tr class="paddingCells">
<td colspan="3"><img src="spacer.gif" border="0" alt="" height="5" /></td>

<tr class="bottomCells">
<td bgcolor="#303400" colspan="7">
<img src="spacer.gif" border="0" alt="" height="1" /></td>

I found that the main menu worked in my primary test browser (Opera) a little bit slower than before. At least Opera suffers the more complex structure, which gives better presentation for Netscape 4.x browsers. That's why I don't recommend to create more complex structures, which I have used. In in the basic structure has been used nested tables I counted that Netscape 4.x needs over 50% percentage more code than modern browsers in order to get reasonable good result. Compared to the minimum HTML-encoding it might be necessary to add because of Netscape 4.x over double quantity of HTML-code! Because of this reason it is quite questionable to support Netscape 4.x series browsers.

#Pages table, #PagesEn table {width:136px; table-layout:fixed} /* When the fixed table layout algorithm has been used the widths of individual cells must exactly match with the width of the whole table. */
#cell1,#cell2, #cell3,... {height:1px; line-height:1px; font-size:1px}
#cell1 img, #cell2 img, #cell3 img,... {height:1px}
#cell1 img, #cell7 img, td#cell1, td#cell7 {width:1px}
#cell4 img, td#cell4 {width:105px}
.paddingCells td {line-height:5px; font-size:5px; height:5px}
div.pageGroup td {height:15px; line-height:15px; padding:0}
/* Cells, which have actual links. Without this definition table rows are don't have the same heights as new MS IE and Opera browsers. This solution doesn't work properly in MS IE 4.x for Windows because only a part of cell have correct line height values. */

Old-fashioned HTML 3.2 style structure solutions cause additional work and they are difficult to get work exactly correct in new Mozilla Gecko based browsers. For new browsers it would be more reasonable to take off additional rows and (if rowspan attributes have been used) at the same time also all additional columns by using display:none for the additional table rows (to the tables of the main menus remain then three columns). In order to do that additional table rows must have id or class attributes (for example tr.topCells, tr.paddingCells, tr.bottomCells {display:none}). In this case it is possible to define real padding and border properties for the container element of the main menu. At this way Netscape 4.x works according to HTML 3.2 guidance and newer browser guided by CSS. I have however noticed, that setting the line-height property doesn't always help getting the correct result in Mozilla Gecko browsers (a test page[S]).

The previous mentioned solution doesn't work properly either in MS IE 4.x for Windows because it doesn't support display:none for table rows. If additional rows and columns for Netscape 4.x have been generated with scripts documents don't conform with (X)HTML specifications. I don't fine any fully satisfactory solution for MS IE 4.x for Windows when text links have been used. If menus will be created on fly with JavaScript (like DHTML Menu Builder does), they can be different for Netscape 4.x and other browsers. But generating menus with scripts is also problematic.

The smartest and the best working result for MS IE 4.x for Windows and Netscape 4.x browsers can be achieved only if all links are images. I don't change all links as image links because they cause so much additional work. If some favors image links it is not in my mind reasonable to encode menus by hands, even if the site of the TechsOfTheWeb.Com teaches, how to use images in dynamic menus. Because MS IE 4.x for Windows and Netscape 4.x series browsers are not anymore very common and they are quite buggy, I don't regard personally as reasonable giving full possible support for them. When menus are intended to encode by using code editors I recommend to use text links with necessary spacer images. In my mind the only reasonable alternative for this is to create menus with commercial applications like Macromedia Dreamweaver and DHTML Menu Builder. Indeed dynamic menus, which have been created with these applications have presumably stability problems at least in some browsers.

Presentation of menus can get better to set true or illusory transparent menus and shadows.

Browser-specific notes:

  1. For Netscape 6.2+/ Mozilla 0.9.4+/ at least as new other Mozilla Gecko browsers can set well-working real transparent sharp-edged menus and shadows by using the -moz-opacity property.

  2. For Opera 6.x+ browsers can set well-working half-transparent sharp-edged menus and shadows by using PNG-background images (MS IE doesn't support transparency in PNG-images). (A model image[S].)

  3. For MS IE 5.5+ for Windows transparent menus and soft-edged shadows can be made by using the proprietary filter property, but it is worth to note that for MS IE 5.5 can set only one effect for one element (a link to CSS-notes[S]). For example soft shadows has the following CSS: filter:progid:DXImageTransform.Microsoft.Shadow(color='#777777', Direction=135, Strength=5);. From the collection of Dynamic Drive can be found a ZIP-file, which can be found a model of a dynamic menu, which use the filter property (Top Navigational Bar IV). Indeed the menu has problems with Opera, which I have mentioned in the previous section[S].

  4. For other browser than new MS IE and Mozilla Gecko can be set transparent GIF-images. Certain pattern can create rough transparency.

Dynamic Drive: Top Navigational Bar IV; Macromedia; TecsOfTheWeb.Com: Using and Manipulating Dropdown Windows; xFX JumpStart: DHTML Menu Builder.

I explain some matters also in the browsing advice[S] - most pages has a short cut to this help (the question mark Apua).