By Alan Gresley and Duncan Hill.
This article and menu variations is always growing and being updated.
One of the most popular CSS base dropdown menus were first seen in 2003 with the Sons of Suckerfish dropdown menus. Some javascript was needed to make it work in Internet Explorer 6 which then had around a 70 percent browser share and coming in second was Internet Explorer 5. Now three years down the evolutionary track brings the Sons of Ursidae dropdown menus with a possible 99% browser support and only a few hacks for IE6/IE5.5. Like its cousin the Sons of Suckerfish menu, but with some major differences, the Sons of Ursidae menu has properties and values which allow for a more flexible menu design. With the support in most browsers for CSS2 standards in 2007, a lot of the CSS styling of 2003 is becoming unnecessary.
<li> element in IE 6 and earlier.Please note that these type of menus will not work in some browsers. The ideal situation is that when the browser fails with the CSS, the menu will appear at the bottom of the page only partially styled. But be warned, they could fail and just ruin the page completly so thorough testing in most if not all browsers is needed.
To start with we have some nice clean code:
<div id="menu"><ul id="navigation" class="main"><li><a href="#">Canidae</a></li><li><a href="#">Ursidae</a><ul><li><a href="#">Ursinae</a><ul><li><a href="#">Brown Bear</a><li><a href="#">American Black Bear</a><li><a href="#">Polar Bear</a></li><li><a href="#">Asiatic Black Bear</a><li><a href="#">Sloth Bear</a><li><a href="#">Sun Bear</a><li><a href="#">Auvergne Bear</a></li><li><a href="#">Etruscan Bear</a></li><li><a href="#">European Cave Bear</a></li><li><a href="#">MacFarlane's Bear</a></li></ul></li><li><a href="#">Tremarctinae</a><!-- etc. --></li></ul></li><li><a href="#";>Mephitidae</a></li></ul></div>The CSS is similar to that of Sons of Suckerfish menus, but with a few major differences:
div#menu {
width:12em;
}
ul#navigation{
font-size: 90%;
}
ul#navigation, ul#navigation ul {
padding: 0;
margin: 0;
list-style: none;
}
ul#navigation li {
line-height : 1.35em;
position: relative;
float: left;
}
ul#navigation li li {
float: none;
}
The major change in the CSS is the widths set for the <li> and <ul> have been removed since this is inherited to all <li> and <ul> elements which would have to be overruled by a more specific selectors. In 2003, the widths for the <li> were needed by Opera, but Opera 9 doesn't need the width. The full significance and praticality for the removal of the width property will be seen in a later stage of this article. There is an addition of position:relative for the <li> element. Like the Sons of Suckerfish vertical menus the Sons of Ursidae has the property and value position:relative for the <li> element which creates a containing block for the absolutely positioned child <ul> element.
#navigation a {
display: block;
width: 9em;
color: #006600;
background-color: #b0efbe;
}
ul#navigation a:hover {
color: #000;
background-color: #99e1b1;
}
The only width that is given is for the <a> element.
The next few selectors hide the various child submenus when not hovered.
ul#navigation li ul {
position: absolute;
left: -999em;
}
#navigation li:hover ul ul, #navigation li.sfhover ul ul {
left: -999em;
}
The next selector shows each submenu when it's parent is hovered. Because the <li> element has the property and value position:relative. The position left for the <ul> element becomes left: 0; and the property margin-left: 100%; is what places the next child <ul> element to the side of its parent <li> element.
#navigation li:hover ul, #navigation li li:hover ul, #navigation li li li:hover ul {
top: 0;
left: 0;
margin-left: 100%;
}
Please note that the properties and values left: 0; and margin-left: 100%; is on the above selector #navigation li:hover ul reveals the submenu of the parent <li> element when hovered. The Sons of Suckerfish vertical menu has the properties and values left: auto; and margin-left: 11.05em; on the selector ul#navigation li ul. This is partly the reason for the submenus becoming sticky in IE7. For an answer as to why, please see the Sticky Sons of Suckerfish article on this site.
Next we need to add the javascript for Internet Explorer 6 an earlier. Instead of inserting the javascript into the header, we can have the javascript in an external file, linked to within a conditional comment that only IE6 sees. The lt in the conditional comment refers to versions of Internet Explorer earlier than 7. The code will look like this.
<!--[if lt IE 7]>
<script type="text/javascript" src="sfhover.js"></script>
<![endif]-->
And the javascript will look like this:
sfHover = function() {
var sfEls = document.getElementById("navigation").getElementsByTagName("LI");
for (var i=0; i<sfEls.length; i++) {
sfEls[i].onmouseover=function() {
this.className+=" sfhover";
}
sfEls[i].onmouseout=function() {
this.className=this.className.replace(new RegExp(" sfhover\\b"), "");
}
}
}
if (window.attachEvent) window.attachEvent("onload", sfHover);
More about Sons of Suckerfish javascript that mimic dynamic psuedo classes.
The javascript must be saved as a javascript file with a .js extension. Lets have a look at what we have with example one.
Now let's let loose a major feature of the Sons of Ursidae menu. It is a full-blooded convert. Let's repeat two previously stated selectors with different values to overrule the previous values. The selectors with the new values must appear after the first selectors in the CSS to work due to the cascade of stylesheets. The new values show the first submenu as a dropdown. The changes are top: 100%; which allows the first submenu to appear below the parent <li> element. Because this element has the property and value position:relative, it is the containing block for the child elements and any value of position or length of margins for a element within it will use the parent <li> element position, width and/or height as a reference.
The other change is margin-left: 0; which simply overrules margin-left: 100%;. The below CSS also has the incasing div#menu with a width of width:100%; to show a horizontal menu. The CSS is.
/* ****DISPLAYS HORIZONTAL MENU**** */
#navigation li:hover ul {
top: 100%;
margin-left: 0;
}
div#menu {
width:100%;
}
Let's have a look at what we have with example two.
Notice that the selector is remarked. If the selector is remarked out the Sons of Ursidae menu is vertical. If shown to the browser as seen above the Sons of Ursidae menu is horizontal. This is done by moving the */ for the remark closing to the end of the section of the CSS. Good if you are not decided and swinging:
/* ****DISPLAYS HORIZONTAL MENU****
#navigation li:hover ul {
top: 100%;
margin-left: 0;
}
div#menu {
width:100%;
}
*/
The second generation submenu is wrapping because of the length of the text for the link is of greater width than the submenu. To make any of a particular generation of submenu wider, these new selector are added to the CSS:
ul#navigation li li a {
width: 11em;
}
ul#navigation li li li a {
width: 14em;
}
We can make some room around the text with the addition of padding to this selector:
#navigation a {
display: block;
width: 9em;
color: #006600;
background-color: #b0efbe;
padding: 4px 0.5em;
}
Let's have a look at what we have with example three.
Now we will give each menu item a border. Adding borders to menus like this where the menu items sit against each other have resulted in a lot of different methods. Another thing is that margins can be difficult to line up. Two avoid the use of creeping margins, all that has to be done is to add a left and bottom border for each <ul> element and add a top and right border to the #navigation a selector. The last thing needed to make the borders look right for the top level menu is positioning the ul#navigation element by either floating left or right or by absolute positioning:
ul#navigation{
font-size: 90%;
position:absolute;
left:0;
}
ul#navigation, ul#navigation ul {
padding: 0;
margin: 0;
list-style: none;
border-left: 1px solid #238126;
border-bottom: 0.04em solid #238126;
}
#navigation a {
display: block;
width: 9em; /* ****CHANGE-MENU**** */
color: #006600;
background-color: #b0efbe;
padding: 4px 0.5em;
text-decoration: none;
border-top: 0.04em solid #238126;
border-right: 1px solid #238126;
}
To bring the child submenu closer to the parent submenu we alter the un-tampered left: 0; value which now becomes left: -1px;:
#navigation li:hover ul, #navigation li li:hover ul, #navigation li li li:hover ul {
top: 0;
left: -1px;
margin-left: 100%;
}
The menu is basically complete example four and with some further style example five.
At one stage in this menu's development, I had a special style for the #navigation li ul selector. The style was a width for this element so Opera would show the same as FF and IE, which is for the submenus in a horizontal menu showing vertical instead of horizontal. Just before I had launched the site I made a change and instead removed the width and added a new #navigation li li selector instead. To this selector I gave the style float:none. The result in Opera was the desired and correct result of the submenus showing horizontal. All was well with FF and IE7 but it made quite a mess in IE6. The first step was to hide the #navigation li li selector style form IE6 with a child selector #navigation>li li. The next step was to give only IE6 the width for the #navigation li ul selector. The simple rule is that whatever the width a submenu <a> element has the <ul> element that contains it must be 1em wider. So the following style:
ul#navigation li li a {
width: 11em;
}
Will be followed by a IE5.5 and IE6 only style:
ul#navigation li ul {
width: 12em;
}
For the vertical menus only, the following style must be given to IE6 and IE7:
ul#navigation li li { /* Needed for IE6 and IE7 for vertical menus */
float: left;
}
This article was created in April, 2007 and last updated on the 5th of November, 2007