RSS Feed Twitter Posts RSS Comments RSS

Monday, October 5, 2009

Float-drop CSS-only multilevel dropdown menu

Dropper Dropdown Multilevel Menu:

A multilevel CSS only dropdown menu

same details apply as the single level menu:

  • This menu is fixed width for simplification purposes.
  • This menu uses no javascript.
  • This menu uses no extra html.
  • This menu is keyboard accessible without javascript.
  • This menu is cross-browser (tested in: IE5.5-IE8, Firefox, Opera, Safari(PC) and Google Chrome.).
  • This menu is valid css/html.
  • This menu was invented by me, simplified and improved with the help of Paul O'Brien and Anton P.

more details:

Demonstration of the Multilevel CSS Dropdown:

You can view it as a external page here

Example

HTML Code for the full multilevel dropdown menu (my original version):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>TH - CSS Only Multilevel Dropdown</title>
<style type="text/css">
/*made by Timo Huovinen*/

ul {
    list-style-type:none;
    margin:0;
    padding:0;
}

#navigation {
    height:25px;
}
.nav {
    position:absolute;
    width:1000px;
}
li {
    float:left;
}
.link {
    position:relative;
    width:300px;
    height:10025px;/*10000 + 25*/
    margin-top:-10000px;
}
.nav a {
    position:relative;
    display:inline-block;
    width:300px;
    background:#9C3;
    height:25px;
}
.nav ul {
    float:left;
}
.sub li {
    clear:left;
    position:relative;
}
.sub li a {
    margin-right:-1px;
}

a.main, .sub a.submain {
    height:25px;
    background:yellow;
    float:left;
    margin-right:-299px;
    margin-top:10000px;
}


.subs {
    visibility:hidden;
    height:25px;
    top:-10000px;
}
.subs a {
    visibility:visible;
}

.sub ul li {
    left:300px;
    top:-25px;
}


.subs ul a {
    background:#CC6;
    margin-right:-2px;
}



.nav a:hover,
.nav a:focus,
.nav a:active{
    background:orange;
    margin-right:0;
}
.subs li a:hover,
.subs li a:focus,
.subs li a:active{
    background:#C93;
}





/*OPERA fix*/
.sub:hover {
    clear:left;
}
.sub ul:hover {
    clear:left;
}




/*multi multilevel*/
.subs .subs  {
    top:-10025px;
}
.subs .subs ul a {
    background:#099;
    margin-right:-3px;
    color:#fff;
}
.subs .subs ul a:hover,
.subs .subs ul a:focus,
.subs .subs ul a:active{
    background:#06F;
    margin-right:0;
}

</style>
<!--[if IE 7]>
<style type="text/css">
.subs {
    visibility:visible;
    min-width:299px;
}

/*multi multilevel*/
.subs .subs {
    min-width:298px;
}
</style>
<![endif]-->
<!--[if lte IE 6]>
<style type="text/css">
.subs {
    width:299px;
    height:20025px;/*10000 + 10000 + 25*/
   
    margin-top:-10000px;
    margin-bottom:-10000px;
   
    position:relative;
    top:-20000px;/*10000 + 10000*/
    visibility:visible;
}
.subs a.submain, .subs ul li {
    position:relative;
    top:20000px;/*10000 + 10000*/
}
.subs ul li {
    top:19975px;/*10000 + 10000 - 25*/
}

/*multi multilevel*/
.subs .subs {
    top:-25px;
    width:298px;
}
</style>
<![endif]-->
</head>

<body>
<div style="position:relative;z-index:1;"><a href="#background1">background 1</a></div>
<div id="navigation">
<ul class="nav">
<li class="link">
    <a class="main" href="#">Main</a>
    <ul class="sub">
        <li><a href="#1">test1</a></li>
        <li><a href="#2">test2</a></li>
        <li class="subs"><a class="submain" href="#2">test2</a>
                    <ul>
                        <li><a href="#subtest1">sub test 1</a></li>
                        <li><a href="#subtest2">sub test 2</a></li>
                        <li><a href="#subtest3">sub test 3</a></li>
                        <li><a href="#subtest4">sub test 4</a></li>
                        <li><a href="#subtest5">sub test 5</a></li>
                        <li><a href="#subtest6">sub test 6</a></li>
                    </ul>
        </li>
        <li><a href="#3">test3</a></li>
        <li class="subs"><a class="submain" href="#4">test4</a>
                    <ul>
                        <li><a href="#subtest1">sub test 1</a></li>
                        <li><a href="#subtest2">sub test 2</a></li>
                        <li><a href="#subtest3">sub test 3</a></li>
                        <li><a href="#subtest4">sub test 4</a></li>
                        <li><a href="#subtest5">sub test 5</a></li>
                        <li><a href="#subtest6">sub test 6</a></li>
                    </ul>
        </li>
        <li><a href="#5">test5</a></li>
        <li><a href="#6">test6</a></li>
        <li><a href="#7">test7</a></li>
        <li><a href="#8">test8</a></li>
        <li class="subs"><a class="submain" href="#9">Everything is possible</a>
                    <ul>
                        <li><a href="#subtest1">sub test 1</a></li>
                        <li><a href="#subtest2">sub test 2</a></li>
                        <li><a href="#subtest3">sub test 3</a></li>
                        <li class="subs"><a class="submain" href="#sub4">SUB test4</a>
                                    <ul>
                                        <li><a href="#subtest1">sub sub test 1</a></li>
                                        <li><a href="#subtest2">sub sub test 2</a></li>
                                        <li><a href="#subtest3">sub sub test 3</a></li>
                                        <li><a href="#subtest4">sub sub test 4</a></li>
                                        <li><a href="#subtest5">sub sub test 5</a></li>
                                        <li><a href="#subtest6">sub sub test 6</a></li>
                                    </ul>
                        </li>
                        <li><a href="#subtest5">sub test 5</a></li>
                        <li><a href="#subtest6">sub test 6</a></li>
                        <li class="subs"><a class="submain" href="#sub7">SUB test7</a>
                                    <ul>
                                        <li><a href="#subtest1">sub sub test 1</a></li>
                                        <li><a href="#subtest2">sub sub test 2</a></li>
                                        <li><a href="#subtest3">sub sub test 3</a></li>
                                        <li><a href="#subtest4">sub sub test 4</a></li>
                                        <li><a href="#subtest5">sub sub test 5</a></li>
                                        <li><a href="#subtest6">sub sub test 6</a></li>
                                    </ul>
                        </li>
                    </ul>
        </li>
    </ul>
</li>
<li class="link">
    <a class="main" href="#">Main</a>
    <ul class="sub">
        <li><a href="#1">test1</a></li>
        <li><a href="#2">test2</a></li>
        <li><a href="#3">test3</a></li>
        <li><a href="#4">test4</a></li>
        <li><a href="#5">test5</a></li>
        <li><a href="#6">test6</a></li>
        <li><a href="#7">test7</a></li>
    </ul>
</li>
<li class="link">
    <a class="main" href="#">Main</a>
    <ul class="sub">
        <li><a href="#1">test1</a></li>
        <li><a href="#2">test2</a></li>
        <li><a href="#3">test3</a></li>
        <li class="subs"><a class="submain" href="#4">test4</a>
                    <ul>
                        <li><a href="#subtest1">sub test 1</a></li>
                        <li><a href="#subtest2">sub test 2</a></li>
                        <li><a href="#subtest3">sub test 3</a></li>
                        <li><a href="#subtest4">sub test 4</a></li>
                        <li><a href="#subtest5">sub test 5</a></li>
                        <li><a href="#subtest6">sub test 6</a></li>
                    </ul>
        </li>
        <li><a href="#5">test5</a></li>
        <li><a href="#6">test6</a></li>
        <li class="subs"><a class="submain" href="#7">test7</a>
                    <ul>
                        <li><a href="#subtest1">sub2 test 1</a></li>
                        <li><a href="#subtest2">sub2 test 2</a></li>
                        <li><a href="#subtest3">sub2 test 3</a></li>
                        <li><a href="#subtest4">sub2 test 4</a></li>
                        <li><a href="#subtest5">sub2 test 5</a></li>
                        <li><a href="#subtest6">sub2 test 6</a></li>
                    </ul>
        </li>
    </ul>
</li>
</ul>
</div>
<div><a href="#background2">background 2</a></div>
</body>
</html>

The Multilevel dropdown was kindly simplified by Anton P:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
               "http://www.w3.org/TR/html4/strict.dtd">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title></title>
    <style type="text/css">
#navigation {
    background: #ccc;
    height: 25px;
}

ul {
    list-style: none;
    margin: 0;
    padding: 0
}

#navigation a {
    text-decoration: none;
    color: #000;
}


/***** ALL LEVELS *****/

ul.nav li {
    zoom: 1;
}

ul.nav a {
    position: relative;
    display: block;
    width: 150px;
    margin-right: -149px;
    height: 25px;
}
ul.nav a:hover,
ul.nav a:focus,
ul.nav a:active {
    margin-right: 0;
}

ul.nav a.main {
    float: left; _display: inline;
    margin-top: 10000px; /* (2) bring back onscreen */
}


/***** LEVEL 1 *****/

ul.nav li.link {
    float: left; _display: inline;
    width: 150px;
    margin-top: -10000px; /* (1) set offscreen distance */
}

ul.nav li.link a {
    background: transparent; /* enables persistent background */
}
ul.nav li.link a:hover,
ul.nav li.link a:focus,
ul.nav li.link a:active {
    background: yellow;
}


/***** LEVEL 2 AND BELOW *****/

ul.nav ul.sub {
    background: green; /* provides persistent background for parent A */
    float: left; /* display:inline breaks IE6 here */
    margin-top: -25px;
    padding-top: 25px;
    margin-bottom: -5000px; /* (4) avoid interaction with subsequent page elements */
                            /* any sufficiently large amount, but Opera has low upper limits */
}
ul.nav ul.sub:hover {
    clear: both; /* Opera fix for A:hover background colours */
}

ul.nav ul.sub li {
    clear: left; /* must clear any immediately preceding LI.has-sub */
}
ul.nav ul.sub li.has-sub {
    float: left; _display: inline;
    _clear: none; /* (5) don't clear any immediately preceding LI.has-sub in IE6 since clearing is not necessary anyway in this browser,
                       * and doing so on an LI.has-sub causes breakage when there are at least two consecutive submenu items both with subsubmenus;
                       * however, we keep the clear on other LIs to work around another bug in which, whenever the first item of a submenu is an
                       * li.has-sub with clear:none and the second item is a normal LI, a one-item-high vertical gap appears before normal LI
                       * unless it has clear:left */
    margin-top: -10000px; /* (1) set offscreen distance */
    height: 25px; /* height of child A... */
    height: 10025px; /* (3) ...which IE6 expands by 10000 to enclose its child A */
}

ul.nav ul.sub a {
    background: #ddd;
}
ul.nav ul.sub a:hover,
ul.nav ul.sub a:focus,
ul.nav ul.sub a:active {
    background: yellow;
}


/***** LEVEL 3 and below *****/

ul.nav ul.sub ul.sub {
    position: relative;
    left: 150px;
    padding-top: 0;
}
ul.nav li.last-child ul.sub ul.sub {
    left: auto;
    right: 150px; /* optionally reverse the submenu direction for the rightmost main menu item */
}

    </style>
<!--[if IE 7]>
<style type="text/css">
ul.nav ul.sub li.has-sub:hover ~ li ul {
    display: none; /* (6) prevents breakage in IE7 when there are at least two consecutive submenu items both with subsubmenus */
}
ul.nav ul.sub li.has-sub:hover ul {
    display: block;
}
ul.nav ul.sub li.has-sub ul {
    z-index: 2; /* (6) see above; alas the fix won't work with :active, but at least we can ensure that menu is visible with keyboard navigation */
}
ul.nav ul.sub li.has-sub ~ li ul {
    z-index: 1; /* (6) see above */
}
</style>
<!--IE7 fullfix using js-->
<script type="text/javascript">
window.onload = function() {
    /*@cc_on
    @if (@_jscript_version == 5.7)
    if (typeof document.body.style.maxHeight != "undefined") { //IE7
        //Define getElementsByClassName for IE<8
        function walkTheDOM (node, func) {
            func(node);
            node = node.firstChild;
            while (node) {
                walkTheDOM(node, func);
                node = node.nextSibling;
            }
        }
        function getElementsByClassName(el, className) {
            var results = [];
            walkTheDOM(el, function (node) {
                            var a, c = node.className, i;
                            if (c) {
                             a = c.split(' ');
                             for (i=0; i<a.length; i++) {
                              if (a[i] === className) {
                               results.push(node);
                               break;
                              }
                             }
                            }
                           });
            return results;
        }

         // For an element el which is the A child of an li.has-sub, this function finds all following sibling LIs of
         // that li.has-sub and sets their child UL, if it exists, to display:none while setting the child UL of li.has-sub
         // to display:block
        var fixSubmenuDisplay = function(el) {
            var siblings = el.parentNode.parentNode.childNodes;
            var elParentFound = false;
            var siblingChildren;
            for (var j=0; j<siblings.length; ++j) {
                if (!elParentFound && siblings[j].nodeType == 1 && siblings[j].tagName == "LI" && siblings[j] == el.parentNode) {
                    elParentFound = true;
                }
                if (elParentFound) {
                    siblingChildren = siblings[j].childNodes;
                    for (var k=0; k<siblingChildren.length; ++k) {
                        if (siblingChildren[k].nodeType == 1 && siblingChildren[k].tagName == "UL") {
                            if (siblings[j] == el.parentNode) {
                                siblingChildren[k].style.display = "block";
                            } else {
                                siblingChildren[k].style.display = "none";
                            }
                        }
                    }
                }
            }
        }

        // For an A child of an li.has-sub, sets the onfocus and onmouseover event to call the fixSubmenuDisplay function
        var nav = document.getElementById("navigation");
        var hasSubs = getElementsByClassName(nav, "has-sub");
        var children;
        var aChild;
        for (var i=0; i<hasSubs.length; ++i) {
            children = hasSubs[i].childNodes;
            for (var j=0; j<children.length; ++j) {
                if (children[j].nodeType == 1 && children[j].tagName == "A") {
                    aChild = children[j];
                    break;
                }
            }
            aChild.onfocus = function() {
                fixSubmenuDisplay(this);
            }
            aChild.onmouseover = function() {
                fixSubmenuDisplay(this);
            }
        }
    }
    @end
    @*/
}
</script>
<![endif]-->

</head>
<body>
<div class="outer">
    <div class="header">
        <p>Jfkd fjd jf <a href="#background1">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background1">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background1">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background1">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background1">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background1">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background1">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background1">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background1">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background1">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background1">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background1">background 2</a></p>
    </div>
    <div id="navigation">
        <ul class="nav">
            <li class="link"> <a class="main" href="#">Main</a>
                <ul class="sub">
                    <li><a href="#">test1</a></li>
                    <li><a href="#">test2</a></li>
                    <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                        <ul class="sub">
                            <li><a href="#">sub test1</a></li>
                            <li><a href="#">sub test2</a></li>
                            <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                                <ul class="sub">
                                    <li><a href="#">sub test1</a></li>
                                    <li><a href="#">sub test2</a></li>
                                    <li><a href="#">sub test3</a></li>
                                    <li><a href="#">sub test4</a></li>
                                </ul>
                            </li>
                            <li><a href="#">sub test3</a></li>
                            <li><a href="#">sub test4</a></li>
                            <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                                <ul class="sub">
                                    <li><a href="#">sub test1</a></li>
                                    <li><a href="#">sub test2</a></li>
                                    <li><a href="#">sub test3</a></li>
                                    <li><a href="#">sub test4</a></li>
                                </ul>
                            </li>
                            <li><a href="#">sub test5</a></li>
                            <li><a href="#">sub test6</a></li>
                        </ul>
                    </li>
                    <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                        <ul class="sub">
                            <li><a href="#">sub test1</a></li>
                            <li><a href="#">sub test2</a></li>
                            <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                                <ul class="sub">
                                    <li><a href="#">sub test1</a></li>
                                    <li><a href="#">sub test2</a></li>
                                    <li><a href="#">sub test3</a></li>
                                    <li><a href="#">sub test4</a></li>
                                </ul>
                            </li>
                            <li><a href="#">sub test3</a></li>
                            <li><a href="#">sub test4</a></li>
                            <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                                <ul class="sub">
                                    <li><a href="#">sub test1</a></li>
                                    <li><a href="#">sub test2</a></li>
                                    <li><a href="#">sub test3</a></li>
                                    <li><a href="#">sub test4</a></li>
                                </ul>
                            </li>
                            <li><a href="#">sub test5</a></li>
                            <li><a href="#">sub test6</a></li>
                        </ul>
                    </li>
                    <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                        <ul class="sub">
                            <li><a href="#">sub test1</a></li>
                            <li><a href="#">sub test2</a></li>
                            <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                                <ul class="sub">
                                    <li><a href="#">sub test1</a></li>
                                    <li><a href="#">sub test2</a></li>
                                    <li><a href="#">sub test3</a></li>
                                    <li><a href="#">sub test4</a></li>
                                </ul>
                            </li>
                            <li><a href="#">sub test3</a></li>
                            <li><a href="#">sub test4</a></li>
                            <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                                <ul class="sub">
                                    <li><a href="#">sub test1</a></li>
                                    <li><a href="#">sub test2</a></li>
                                    <li><a href="#">sub test3</a></li>
                                    <li><a href="#">sub test4</a></li>
                                </ul>
                            </li>
                            <li><a href="#">sub test5</a></li>
                            <li><a href="#">sub test6</a></li>
                        </ul>
                    </li>
                    <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                        <ul class="sub">
                            <li><a href="#">sub test1</a></li>
                            <li><a href="#">sub test2</a></li>
                            <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                                <ul class="sub">
                                    <li><a href="#">sub test1</a></li>
                                    <li><a href="#">sub test2</a></li>
                                    <li><a href="#">sub test3</a></li>
                                    <li><a href="#">sub test4</a></li>
                                </ul>
                            </li>
                            <li><a href="#">sub test3</a></li>
                            <li><a href="#">sub test4</a></li>
                            <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                                <ul class="sub">
                                    <li><a href="#">sub test1</a></li>
                                    <li><a href="#">sub test2</a></li>
                                    <li><a href="#">sub test3</a></li>
                                    <li><a href="#">sub test4</a></li>
                                </ul>
                            </li>
                            <li><a href="#">sub test5</a></li>
                            <li><a href="#">sub test6</a></li>
                        </ul>
                    </li>
                    <li><a href="#">test3</a></li>
                    <li><a href="#">test4</a></li>
                </ul>
            </li>
            <li class="link"> <a class="main" href="#">Main</a>
                <ul class="sub">
                    <li><a href="#">test1</a></li>
                    <li><a href="#">test2</a></li>
                    <li><a href="#">test3</a></li>
                    <li><a href="#">test4</a></li>
                </ul>
            </li>
            <li class="link"> <a class="main" href="#">Main</a>
                <ul class="sub">
                    <li><a href="#">sub test1</a></li>
                    <li><a href="#">sub test2</a></li>
                    <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                        <ul class="sub">
                            <li><a href="#">sub test1</a></li>
                            <li><a href="#">sub test2</a></li>
                            <li><a href="#">sub test3</a></li>
                            <li><a href="#">sub test4</a></li>
                        </ul>
                    </li>
                    <li><a href="#">sub test3</a></li>
                    <li><a href="#">sub test4</a></li>
                    <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                        <ul class="sub">
                            <li><a href="#">sub test1</a></li>
                            <li><a href="#">sub test2</a></li>
                            <li><a href="#">sub test3</a></li>
                            <li><a href="#">sub test4</a></li>
                        </ul>
                    </li>
                    <li><a href="#">sub test5</a></li>
                    <li><a href="#">sub test6</a></li>
                </ul>
            </li>
            <li class="link last-child"> <a class="main" href="#">Main</a>
                <ul class="sub">
                    <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                        <ul class="sub">
                            <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                                <ul class="sub">
                                    <li><a href="#">sub test1</a></li>
                                    <li><a href="#">sub test2</a></li>
                                    <li><a href="#">sub test3</a></li>
                                    <li><a href="#">sub test4</a></li>
                                </ul>
                            </li>
                            <li><a href="#">sub test1</a></li>
                            <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                                <ul class="sub">
                                    <li><a href="#">sub test1</a></li>
                                    <li><a href="#">sub test2</a></li>
                                    <li><a href="#">sub test3</a></li>
                                    <li><a href="#">sub test4</a></li>
                                </ul>
                            </li>
                            <li><a href="#">sub test2</a></li>
                        </ul>
                    </li>
                    <li><a href="#">test1</a></li>
                    <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                        <ul class="sub">
                            <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                                <ul class="sub">
                                    <li><a href="#">sub test1</a></li>
                                    <li><a href="#">sub test2</a></li>
                                    <li><a href="#">sub test3</a></li>
                                    <li><a href="#">sub test4</a></li>
                                </ul>
                            </li>
                            <li><a href="#">sub test1</a></li>
                            <li class="has-sub"> <a class="main" href="#">Sub menu »</a>
                                <ul class="sub">
                                    <li><a href="#">sub test1</a></li>
                                    <li><a href="#">sub test2</a></li>
                                    <li><a href="#">sub test3</a></li>
                                    <li><a href="#">sub test4</a></li>
                                </ul>
                            </li>
                            <li><a href="#">sub test2</a></li>
                        </ul>
                    </li>
                    <li><a href="#">test2</a></li>
                </ul>
            </li>
        </ul>
    </div>
    <p>Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.  Jfkd fjd jf <a href="#background2">background 2</a> jfkd jfldj fdsl.</p>
</div>
</body>
</html>

Update

Anton P, improved his method even more after discovering a bug in IE6, the bug is still partially present in IE7, but only for :active link states.

Update2 (2009.11.04)

I have made a much improved version, using some of Anton P's tricks. I made it specifically with customization in mind, please read its comments to know what each part does.

Update3 (2009.12.10)

I have reduced the amount of IE5-7 fixes to a bare minimum: .nav .sub {width:99%;}.

Update4 (2009.12.23)

I have removed any IE conditional comments, the IE fix is now: .nav .sub {width:100%;}, but it is harmless for normal browsers.
Enjoy :)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>TH - CSS Only Multilevel Dropdown</title>
<style type="text/css">
/***reset default styling***/
.nav,
.nav ul{
    list-style-type:none;
    margin:0;
    padding:0;
}
.nav a {
text-decoration:none;
}
/*CUSTOMIZATION*/
/*i have split the code to have the width/height/color separate from the rest of the code*/
/*COLORS*/
/*here are some default colors, funky colors used for distinctive visibility*/
/*i hope that you can handle colors customization on your own :p*/
.nav {
    background:yellow;
}
.nav a {
    background:#9C3;
color:#000;
}
.nav ul {
    background:red;/*top link persistent background color*/
}
.nav a.main {
    background:transparent;/*so that the top link persistent background works*/
}
.nav ul a.main {
    background:yellow;
}
.nav a.main:hover {
    background:orange;
}
.nav .sub ul a {
    background:#CC6;
}
.nav .sub ul a.main {
    background:yellow;
}
.nav .sub ul a.main:hover {
    background:orange;
}
.nav a:hover,
.nav a:focus,
.nav a:active{
    background:orange;
}
.nav .sub li a:hover,
.nav .sub li a:focus,
.nav .sub li a:active{
    background:#C93;
}
.nav .sub .sub ul a {
    background:#099;
color:#fff;
}
.nav .sub .sub ul a:hover,
.nav .sub .sub ul a:focus,
.nav .sub .sub ul a:active{
    background:#06F;
}
.nav .sub .sub .sub ul a {
    background:#036;
}
.nav .sub .sub .sub ul a:hover,
.nav .sub .sub .sub ul a:focus,
.nav .sub .sub .sub ul a:active{
    background:#006;
}
.nav .colored li a {
background:purple;
}



/*HEIGHT*/
.nav {
height:1.563em;/*you could remove this and clear the float differently, but to me this makes the most sense*/
}
.nav a {
padding:.2em 0;/*apply padding to links, to vertically center them, be careful with horizontal padding in IE5, correct width must be maintained*/
}
.nav a.main {
    height:1.563em;/*needs to be the same as the persistent background trick and so that the sublevels are properly aligned*/
line-height:1.563em;/*not really necessary, but in this specific case it vertically centers the main link text*/
overflow:hidden;/*making it more bulletproof*/
padding:0;/*remove the padding that was applied above*/
}
.nav ul {
padding-top:1.563em;/*persistent background trick*/
margin-top:-1.563em;/*persistent background trick*/
}
.nav ul ul {
position:relative;/*so that it can be moved top/left*/
    top:-1.563em;/*this is the sole reason why the main links must have a fixed height*/
}


/*WIDTH (!IMPORTANT)*/
/*change each width value below, else the dropdown will stop working (:hover will still work in modern browsers because of the opera fix)*/
/*set the link width here*/
.nav .link,
.nav a {
    width:9em;/*same as width*/
}
.nav ul li {
/*force ie8 to float-drop*/
max-width:9em;/*same as width*/
}
/*set the sublink left shift width here (same as width)*/
.nav ul ul {
/*move the sublinks to the side, so they dont overlap*/
    left:9em;/*same as width*/
}
.nav li.reversed ul {/*reverse the direction of sublinks for the last dropdown*/
left:auto;
    right:9em;/*same as width*/
}
/*add the negative value of "width - 1px" here (because css can't do math)*/
/*or (width - 0.063em) where 0.063em is 1px on 16px base size*/
.nav a {
/*makes the links very thin, so that the sublinks can hide inside the main link*/
margin-right:-8.937em;/*make this width - 1px*//*or width - 0.063em*/
}


/*Dropper Dropdown*/
/*supports up to 4 sub-levels in IE5-7, more can be added*/
/*modern browsers already support any amount of sublevels*/
/*made by Timo Huovinen*/

.nav li {
    float:left;/*fixes several IE related bugs, and allows for clearing*/
}
.nav ul {
    float:left;/*necessary for float drop*/
}
.nav ul li {
    clear:left;/*must clear the floated list item inside sublist*/
}
.nav a {
    position:relative;/*needs to have a position, to be above the rest*/
    display:block;
}
.nav a.main {
    float:left;/*necessary for float drop*/
margin-top:10000px;/*bring the links back into view*/
}
.nav .link,
.nav .sub {
margin-top:-10000px;/*hide the links and their containers, opera has low upper limits*/
}
.nav ul {
margin-bottom:-5000px;/*avoid any interaction between the sub's, can be any large size*/
}
/*the main trick, removes the negative right-margin and causes float drop*/
.nav a:hover,
.nav a:focus,
.nav a:active{
    margin-right:0;
}

/*OPERA fix*/
.nav ul:hover,
.nav ul ul:hover {
    clear:left;/*fix for opera sublinks flickering on :hover*/
}
/*background no longer needed*/
.nav ul ul {
    background:transparent;
}


/*IE5-6 + 7 bug fixes*/
.nav .sub {
    width:100%;
}
/*empty rule to fix occassional IE6 tabbing bug, one of the weirdest bug's i have seen.
it seems that this indexes the links together as one? does not happen for everyone, but im leaving it just in case.*/
a, a:hover, a:active, a:focus {}
</style>
<!--I would also suggest adding some javascript to delay the closing of the sublinks, just to make it even better-->
</head>
<body>
<a href="#background1">background 1</a>
<ul class="nav">
<li class="link">
    <a class="main" href="#">Main</a>
    <ul>
        <li><a href="#1">test1</a></li>
        <li><a href="#2">test2</a></li>
        <li class="sub"><a class="main" href="#3">main 1 »</a>
                    <ul class="colored">
                        <li><a href="#subtest1">sub test 1</a></li>
                        <li><a href="#subtest2">sub test 2</a></li>
                        <li><a href="#subtest3">sub test 3</a></li>
                        <li><a href="#subtest4">sub test 4</a></li>
                        <li class="sub"><a class="main" href="#sub4">SUB main 1 »</a>
                                    <ul>
                                        <li><a href="#subtest1">sub sub test 1</a></li>
                                        <li><a href="#subtest2">sub sub test 2</a></li>
                                        <li><a href="#subtest3">sub sub test 3</a></li>
                                        <li><a href="#subtest4">sub sub test 4</a></li>
                                        <li><a href="#subtest5">sub sub test 5</a></li>
                                        <li><a href="#subtest6">sub sub test 6</a></li>
                                    </ul>
                        </li>
                        <li><a href="#subtest5">sub test 5</a></li>
                        <li><a href="#subtest6">sub test 6</a></li>
                    </ul>
        </li>
        <li class="sub"><a class="main" href="#4">main 2 »</a>
                    <ul>
                     <li class="sub"><a class="main" href="#sub4">SUB main 2 »</a>
                                    <ul>
                                        <li><a href="#subtest1">sub sub test 1</a></li>
                                        <li><a href="#subtest2">sub sub test 2</a></li>
                                        <li><a href="#subtest3">sub sub test 3</a></li>
                                        <li><a href="#subtest4">sub sub test 4</a></li>
                                        <li><a href="#subtest5">sub sub test 5</a></li>
                                        <li><a href="#subtest6">sub sub test 6</a></li>
                                    </ul>
                        </li>
                        <li><a href="#subtest1">sub test 1</a></li>
                        <li><a href="#subtest2">sub test 2</a></li>
                        <li><a href="#subtest3">sub test 3</a></li>
                        <li><a href="#subtest4">sub test 4</a></li>
                        <li><a href="#subtest5">sub test 5</a></li>
                        <li><a href="#subtest6">sub test 6</a></li>
                    </ul>
        </li>
        <li><a href="#5">test5</a></li>
        <li><a href="#6">test6</a></li>
        <li><a href="#7">long text link showing what happens</a></li>
        <li><a href="#8">test8</a></li>
        <li class="sub"><a class="main" href="#9">Everything is possible</a>
                    <ul>
                        <li><a href="#subtest1">sub test 1</a></li>
                        <li><a href="#subtest2">sub test 2</a></li>
                        <li><a href="#subtest3">sub test 3</a></li>
                        <li class="sub"><a class="main" href="#sub4">SUB test4 »</a>
                                    <ul>
                                        <li><a href="#subtest1">sub sub test 1</a></li>
                                        <li><a href="#subtest2">sub sub test 2</a></li>
                                        <li><a href="#subtest3">sub sub test 3</a></li>
                                        <li class="sub"><a class="main" href="#sub7">Ultra SUB test7 »</a>
                                     <ul>
                                         <li><a href="#subtest1">sub sub test 1</a></li>
                                         <li><a href="#subtest2">sub sub test 2</a></li>
                                         <li><a href="#subtest3">sub sub test 3</a></li>
                                         <li><a href="#subtest4">sub sub test 4</a></li>
                                         <li><a href="#subtest5">sub sub test 5</a></li>
                                         <li><a href="#subtest6">sub sub test 6</a></li>
                                     </ul>
                         </li>
                                        <li class="sub"><a class="main" href="#sub7">Ultra SUB test8 »</a>
                                     <ul>
                                         <li><a href="#subtest1">sub sub test 1</a></li>
                                         <li><a href="#subtest2">sub sub test 2</a></li>
                                         <li><a href="#subtest3">sub sub test 3</a></li>
                                         <li><a href="#subtest4">sub sub test 4</a></li>
                                         <li><a href="#subtest5">sub sub test 5</a></li>
                                         <li><a href="#subtest6">sub sub test 6</a></li>
                                     </ul>
                         </li>
                                        <li><a href="#subtest4">sub sub test 4</a></li>
                                        <li><a href="#subtest5">sub sub test 5</a></li>
                                        <li><a href="#subtest6">sub sub test 6</a></li>
                                    </ul>
                        </li>
                        <li><a href="#subtest5">sub test 5</a></li>
                        <li><a href="#subtest6">sub test 6</a></li>
                        <li class="sub"><a class="main" href="#sub7">SUB test7 »</a>
                                    <ul>
                                        <li><a href="#subtest1">sub sub test 1</a></li>
                                        <li><a href="#subtest2">sub sub test 2</a></li>
                                        <li><a href="#subtest3">sub sub test 3</a></li>
                                        <li><a href="#subtest4">sub sub test 4</a></li>
                                        <li><a href="#subtest5">sub sub test 5</a></li>
                                        <li><a href="#subtest6">sub sub test 6</a></li>
                                    </ul>
                        </li>
                        <li class="sub"><a class="main" href="#sub7">SUB test7 »</a>
                                    <ul>
                                        <li><a href="#subtest1">sub sub test 1</a></li>
                                        <li><a href="#subtest2">sub sub test 2</a></li>
                                        <li><a href="#subtest3">sub sub test 3</a></li>
                                        <li><a href="#subtest4">sub sub test 4</a></li>
                                        <li><a href="#subtest5">sub sub test 5</a></li>
                                        <li><a href="#subtest6">sub sub test 6</a></li>
                                    </ul>
                        </li>
                    </ul>
        </li>
    </ul>
</li>
<li class="link">
    <a class="main" href="#">Main</a>
    <ul>
        <li><a href="#1">test1</a></li>
        <li><a href="#2">test2</a></li>
        <li><a href="#3">test3</a></li>
        <li><a href="#4">test4</a></li>
        <li><a href="#5">test5</a></li>
        <li><a href="#6">test6</a></li>
        <li><a href="#7">test7</a></li>
    </ul>
</li>
<li class="link reversed">
    <a class="main" href="#">Main</a>
    <ul>
        <li><a href="#1">test1</a></li>
        <li><a href="#2">test2</a></li>
        <li><a href="#3">test3</a></li>
        <li class="sub"><a class="main" href="#4">test4 »</a>
                    <ul>
                        <li><a href="#subtest1">sub test 1</a></li>
                        <li><a href="#subtest2">sub test 2</a></li>
                        <li><a href="#subtest3">sub test 3</a></li>
                        <li><a href="#subtest4">sub test 4</a></li>
                        <li><a href="#subtest5">sub test 5</a></li>
                        <li><a href="#subtest6">sub test 6</a></li>
                    </ul>
        </li>
        <li><a href="#5">test5</a></li>
        <li><a href="#6">test6</a></li>
        <li class="sub"><a class="main" href="#7">test7 »</a>
                    <ul>
                        <li><a href="#subtest1">sub2 test 1</a></li>
                        <li><a href="#subtest2">sub2 test 2</a></li>
                        <li><a href="#subtest3">sub2 test 3</a></li>
                        <li class="sub"><a class="main" href="#sub7">SUB test7 »</a>
                                    <ul>
                                        <li><a href="#subtest1">sub sub test 1</a></li>
                                        <li><a href="#subtest2">sub sub test 2</a></li>
                                        <li><a href="#subtest3">sub sub test 3</a></li>
                                        <li><a href="#subtest4">sub sub test 4</a></li>
                                        <li><a href="#subtest5">sub sub test 5</a></li>
                                        <li><a href="#subtest6">sub sub test 6</a></li>
                                    </ul>
                        </li>
                        <li><a href="#subtest4">sub2 test 4</a></li>
                        <li><a href="#subtest5">sub2 test 5</a></li>
                        <li><a href="#subtest6">sub2 test 6</a></li>
                    </ul>
        </li>
    </ul>
</li>
</ul>
<a href="#background2">background 2</a>
</body>
</html>

How it works:

Same as the simplified dropdown but i have nested the dropdowns, now any link hovered withing the dropdown expands, causing a float drop for every level

Info:

This dropdown was created because of my hate of javascript based dropdowns.
This dropdown serves to proove that it is indeed possible to create a true css only dropdown.
It took about a month to make the dropdown (from idea to reality), and a week to simplify it with the help of Paul and another week to make it multilevel.
And another several months to reach it's current state.
It was also featured as a quiz on Paul's CSS quizzes on Sitepoint (my forum's alias is YuriKolovsky).

Terms of use:

The software referenced within this license is distributed free of charge and free from any warranty. It may be used freely for any purpose whatsoever. The author created and released this work because he is genuinely a Nice Person!

Users are encouraged to use, modify, distribute, improve and otherwise manipulate the code. After all, it’s free.

The author sincerely hopes that end users enjoy and appreciate the hard work that went into creating it, and would appreciate being referenced in future modifications of the code since it was based on the author’s original concept and work.

Users are nonetheless encouraged to provide reciprocity whenever possible as it provides positive reinforcement and encouragement to the author. Furthermore, the minimum reciprocation I ask is to leave a ‘thank you’ comment in the area below:

11 comments:

paintedswan said...

This is really brilliant work! Thank you so much for sharing this to the world.

I'm curious -- is there any way to have the text in the vertical center of the color blocks? I noticed they tend to display toward the top.

Thanks again for all your hard work.

Timo Huovinen said...

if each link contains only 1 row of text then you could get away with line-height, as in you set the link to have a height:24px; and line-height:24px;

modern browser also support
display:table-cell;
vertical-align:middle;

i also suggest using padding-top + padding-bottom to center text, this way even if it does grow too bit it will remain centered

you can use any known methods of vertical centering on block elements.

useful links:
http://www.w3.org/Style/Examples/007/center
http://www.student.oulu.fi/~laurirai/www/css/middle/

paintedswan said...

I got it to work, thank you so much for your quick and helpful reply. :)

Timo Huovinen said...

paintedswan has discovered a bug in Anton P's version in IE5-7.

i have fixed the bug in IE5-6 by adding some conditional comments to his version, i have also emailed him about the issue and will post his "fixed" version as soon as i have it.

in the meanwhile i suggest you use my version, or my "easier to customize" version i just added :)

paintedswan said...

Timo,

Thanks for posting the bug, and I'm glad a fix might be coming soon.

I really like your more "easily customizable" version, it's much more neatly organized.

I have two questions about it, however -- and I apologize in advance if the questions are elementary in nature.

First, I would like the "Main" link at the top to be a certain color in the hover state (say blue, for instance), and for it to stay that color when I scroll down through the submenu's (which should stay a different color from the "Main" link at the top). I should add that I'd like the Main link to have a clear background when it's not being used. I was able to acheive this in Anton's version, but I'm having trouble duplicating this effect in yours. Do you have any advice on how to make this possible?

Also, the second question may be a bit more obvious to some -- but I'd like to know how to make the #navigation div flush with the top of the screen, without any space in between.

Hope this isn't too many questions. Thanks again for all your wonderful help.

Timo Huovinen said...

to make the top link behave as you describe add this to the css

.sub {
border-top:solid red 25px;
margin-top:-25px;
}
a.main {
background:transparent;
}

its a little border/background fakery :)

if you want the navigation to stick to the top, then you need to remove the margins and paddings from the css body element

i suggest using a css reset [google it] or just this css
* {
margin:0; padding:0;
}

i also found a different version of anton p's version, that i will post shortly, where he claims the bug is not present, the fixed version is a direct simplification of my version, while the broken version is a version of another persons version of my version. hope that makes it clearer :P

paintedswan said...

Awesome stuff! Thanks so much for the help on altering your version a bit -- and am glad to see the fix was already available.

Timo Huovinen said...

updated "easier to customize" version to add the a.main:hover state
so that you can add a color to the hover state of the main link

for further technical questions email me at timoh89 at gmail point com

otrocorreo said...

this really works, i used for my website.
thanks for the tips ;)

rickatucdavis said...

Any way to use a variable unit (like em) instead of px for some of the sizing. I note that doing a text-only zoom will cause menu items to start to overlap.

Timo Huovinen said...

@rickatucdavis as far as I know, it's already in em's

Post a Comment