RSS Feed Twitter Posts RSS Comments RSS

Sunday, September 20, 2009

Timo's float-drop CSS-only dropdown menu - simplified

Dropper Dropdown Menu:

A refined CSS only dropdown menu
  • The worlds most accessible dropdown menu.
  • It is fixed width for simplification purposes.
  • It is uses no javascript.
  • It is uses no extra html.
  • It is keyboard accessible without javascript.
  • It 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.

more details:

  • It uses margins to hide content.
  • This menu uses float-drop to drop the links into view.
  • IE6 keyboard tab bug fix provided by Paul O'Brien.
  • Tip to use tabindex to add "opera keyboard support" given by Stu Nicholls, now removed as it confused the tabbing order in other browsers.
  • Tip: to access the links with a keyboard in opera, press Ctrl+Up & Ctrl + Down.
  • Tip: to access the links with a keyboard in safari4, enable tabbing in preferences/advanced/press tab to highlight each item on webpage.
  • Max height to hide content is of 303024px (18939em @base 16px) which is the height used on the worlds highest website although a height of 32767px is the recommended maximum that has been tested to be the max in opera and safari.
  • Ugly vibrant colors used on purpose.

Demonstration of the Dropdown:

Example

HTML Code for the full dropdown menu:

<!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 Dropdown</title>
<style type="text/css">

.nav, .nav ul {
    list-style-type:none;
    margin:0;
    padding:0;
}
.nav a {
    text-decoration:none;
}
/*IE5 list fix*/
.nav .sub li {float:left;}
.nav .sub > li {float:none;}
#navigation {
    position:relative;
    height:25px;
    background:#ebebeb;
    z-index:10;
}
.nav {
    position:absolute;
    visibility:hidden;
}
.nav .link {
    width:300px;
    margin-top:-10075px;
    float:left;
}
.nav a {
    position:relative;
    display:block;
    height:25px;
    line-height:25px;
    text-decoration:none;
    color:#000;
    z-index:10;
    visibility:visible;
}
.nav .sub a {
    background:orange;
    margin:0 -1px 0 0;
    width:300px;
}
.nav .sub {
    float:left;
    background:#F90;
    padding-top:25px;
    margin-top:-25px;
}
.nav a.main {
    width:300px;
    height:25px;
    line-height:25px;
    margin-top:10075px;
    margin-right:-299px;
    float:left;
}
.nav a.main:hover, .nav a.main:focus, .nav a.main:active {
    margin-right:0;
    background:#000;
    color:#fff;
}
.nav .sub a:hover, .nav .sub a:focus, .nav .sub a:active {
    margin:0 0 0 0;
    background:#333;
    color:#fff;
}
/*empty rule to fix occassional IE6 tabbing bug, one of the weirdest bug's i have seen.*/
a, a:hover, a:active, a:focus {}
/*Opera fix*/
.sub:hover {
    clear:both;
}
</style>
</head>
<body>
<div id="navigation">
    <ul class="nav">
        <li class="link"> <a class="main" href="#m1">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>
            </ul>
        </li>
        <li class="link"> <a class="main" href="#m2">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>
            </ul>
        </li>
        <li class="link"> <a class="main" href="#m3">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>
            </ul>
        </li>
    </ul>
</div>
</body>
</html>

How it works (Visual Example):


content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content : content
The two boxes are floated to the left, if one expands then they both don't fit in the same width making the latter one to drop, thats how float drop is used to achieve the effect, but in the real example we use negative margins to remove 99% of the width, and margin:0 on hover to restore it.

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.
It was also featured as a quiz on Paul's CSS quizzes on Sitepoint (my forum's alias is YuriKolovsky).

Update:

To add, if you click a blank link (href="#") it will keep the link open, this is actually a good thing as it can simplify the usability, there is also the side effect in some browsers where if you click a link, and then press the back button to return, the dropdown link will remain highlighted, this is a browser feature, and the only known way to remove it, is to remove tabbing (remove the a:active and the a:focus)

Update2:

people have been asking how to change the width, here is how: change from 300 to 150px wide.
.nav .sub a {
    width:300px;
}
.nav a.main {
    margin-right:-299px;
}

to

.nav .sub a {
    width:150px;
}
.nav a.main {
    margin-right:-149px;
}

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:
»»  read more