Dropper Dropdown Multilevel Menu:
A multilevel CSS only dropdown 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: