summaryrefslogtreecommitdiff
path: root/old/published/Webmonkey/css-dropdowns.txt
blob: cef1ec7585b67752c501616aa3dfcc4ada0e4305 (plain)
1
There's nothing that strikes fear in the heart of CSS coders like a design mock up that includes drop down menu items. While many will argue that drop down menus are a poor design choice to begin with, sometimes there's just no getting around it -- the client gets what the client wants.

Fortunately creating drop down menus isn't as hard as it used to be. In fact, you can even create them using just HTML and CSS with a tiny bit of Javascript to ensure that good old standards confused IE shares in the drop down fun.

How to do it? Well grab a cup of coffee and let's get to work.

== Getting started, the HTML ==

We're going to design a horizontal menu with three items that list sub-items in drop down menus and a fourth that's just a top level element. Here's what the HTML looks like:


<pre>
<ul id="nav">
	<li><a href="">Home</a></li> 
    <li><a href="">Web</a> 
      <ul> 
        <li><a href="">Browser</a></li> 
        <li><a href="">Search</a></li> 
      </ul> 
    </li> 
    <li><a href="">Monkey</a> 
      <ul> 
        <li><a href="">Eating Banana</a></li> 
        <li><a href="">Throwing Poop</a></li> 
      </ul> 
    </li>
    <li><a href="">Contact</a> 
      <ul> 
        <li><a href="">Via Web</a></li> 
        <li><a href="">Via Phone</a></li> 
        <li><a href="">Via tin can and string</a></li> 
      </ul> 
    </li> 
	 
</ul>
</pre>

As you can see it's a pretty basic HTML list, with some nested lists for our sub elements. I've given it an id of "nav" since we'll need that to employ a little JavaScript here in a bit. But first let's add a little style. 

== Polishing with CSS ==

Paste this code into some style tags in the head of your HTML page (or in a separate, linked stylesheet if you prefer:

<pre>
ul {
	margin: 0;
	padding: 0;
	list-style: none;
}
ul li {
	position: relative;
	float: left;

}
li ul {
	position: absolute;
	top: 30px;
	display: none;
}
ul li a {
	display: block;
	text-decoration: none;
	line-height: 20px;
	color: #000;
	padding: 5px;
	background: #CC0;
	margin: 0 2px;
}

ul li a:hover { background: #66F; }
li:hover ul, li.over ul { display: block; }
</pre>

Okay, so what's going on here? Well first we set up our list by getting rid of any styling along with any margins and padding.

Then we move on to the <code>li</code> elements positioning them relatively and floating them to the left. If you're looking to build a horizontal menu, don't float the <code>li</code> elements. Notice we've also given them a width of 100 pixels. You can adjust this to suit your menu items, but do apply a width otherwise your drop down elements will be a bit wonky.

next up are the nested lists which get an absolute positions 30 pixels from the top of their parent element. Why 30? Well that leads us to the next item, our link styles. Notice we have a line-height of 20 pixels and 5 pixels of padding on all sides. So, 20px + 5px top padding + 5px bottom padding, gives our menu a total height of 30px. The positioning on the nested lists ensures that they appear just below the top level menu items.

The last item in our styles definition is the guts of the operation. We use the <code>:hover</code> pseudo class to display our previously hidden drop-down elements. Now you may be wondering, what's up with that <code>.over</code> class in there? There's no <code>.over</code> class in our HTML... true, but there will be in minute, read on.

The rest of the styles on the a elements are just some garish colors to ensure that you can see the results. Obviously you can come up with a better color scheme for your own work.

Test your page in the browser and it should work. Well, unless you happen to have IE 6. But hey, who cares about IE 6? Those people are living in the dark anyway. It's the mantra of many a designer, but let's face it skipping IE 6 leaves out upwards of 50 percent of your visitors so we should probably do something for them.

== Compensating for IE 6 ==

In order to get IE to understand this fancy W3C standards compliant code we've written, we're going to need a little JavaScript function. There are number of ways to do this, but I'm fond of a very oldie but goodie that we'll borrow from A List Apart's famous, [http://www.alistapart.com/articles/dropdowns/ Suckerfish Drop Down technique].

Here's what the code looks like:

<pre>
startList = function() {
if (document.all&&document.getElementById) {
navRoot = document.getElementById("nav");
for (i=0; i<navRoot.childNodes.length; i++) {
node = navRoot.childNodes[i];
if (node.nodeName=="LI") {
node.onmouseover=function() {
this.className+=" over";
  }
  node.onmouseout=function() {
  this.className=this.className.replace(" over", "");
   }
   }
  }
 }
}
window.onload=startList;
</pre>

Essentially what this does is grab our top level "nav" id and then use it to parse through and temporarily insert a class "over" to all our second level <code>li</code> elements. That will allow IE 6 to recognize our menus.

== Conclusion ==

And there you have it, standards compliant drop down menus that work across browsers (note that IE 5 will choke on this menu, if you really need to support IE 5, you're going to have to use some conditional comments).

Obviously our example is pretty ugly, but we're confident you can come up with functional and nice looking drop down menu using the basic outline here.

If you want to get really fancy, try adding this code to your link definition:

<pre>
ul li a {
	display: block;
	text-decoration: none;
	line-height: 20px;
	color: #000;
	padding: 5px;
	background: #CC0;
	margin: 0 2px;
	display: block; 
    -webkit-transition-property: background-color;
    -webkit-transition-duration: 1s;
    -webkit-transition-timing-function: ease-in;
}
</pre>

That'll leverage some experiment CSS 3 transition effects to give your rollovers a gradual fade in/fade out transitions. Of course it will only affect Apple's Safari web browser.