CSS Drop Down Menus
CSS Navigation, Fluid & Accessible
As a follow up to the menus that were developed with Seo Consultants directory. This is a Technical Introduction (read: the boring bit) for a follow up tutorial for those that would like to know the how.
Search Engine Friendly, Accessible DropDown menus using Pure CSS are within our grasp. Certainly at this time of writing (Jan 2005), newer browsers like FireFox and Opera have great CSS2 support and allow us to use the dynamic :hover pseudo-class on all elements.
Microsoft's Internet Explorer (IE), however, does not support
:hover on anything except
<a>, anchor, elements and also it's support for Child Selectors is sadly lacking.
A fuller explanation of the above two terms are outwith the scope of the tutorial. This explanation is intended to provide a stable cross browser solution available to us at this time, using semantically correct HTML and the minimum of IE CSS workarounds for the above two problems.
The aim here is to make fluid solutions which visually expand as the browsers text is resized and is also as semantically correct, to Search Engines and other non-CSS environments, as possible.
Getting IE to Lend Its Support
Before we get to the nitty gritty of CSS coding the two menus, (follow that link if you want to take a shortcut), let me explain that these menus do take advantage of Microsoft proprietary code. IE while not choosing to support all of the W3C's CSS recommendations do offer some proprietary code and support features, much like all other browsers. I think this is a pretty good option that we actually have a method to give IE it's proprietary code without complex browser-sniffing or using CSS hacks. At least this way we can help IE users enjoy some of benefits of visual CSS effects while not compromising other users.
Enter Microsoft Conditional Comments. Each different IE/Windows version can be detected, and there is much more detail about how they can be used by following that link but suffice to say because I don't want to be incorporating multiple IE stylesheets and to keep things as simple as possible for these particular menus, I'm using a general one to target all versions of IE/Windows:
<!--[if IE]> <style type="text/css" media="screen"> </style> <![endif]-->
By putting that comment after all the other CSS rules, to ensure the integrity of the Cascade, we're asking IE/Windows only to read and apply whatever styles or linked stylesheet are within that comment. Any other browsers will ignore it.
"A word from our sponsors...."
So now we've got a way to target IE only, how can we get it to support
:hover on non-anchor elements?
IE also provides support for HTML Components (HTCs)
"HTML Components (HTCs) provide a mechanism to implement components in script as Dynamic HTML (DHTML) behaviors. Saved with an .htc extension"
What's that? - Again further explanation of these files is outwith the scope of this document, but fortunately some very clever people have already written a lot of HTC files to encourage IE to mimic various CSS features via DHTML behaviours
The one I'm using for these menus is whatever:hover written by Peter Nederlof. It has been recently updated (21 Jan 2005) to help overcome a "quirk" we found while trying to write these menus. Thanks Peter!
The reason I like this solution and am using it here, is that you don't need to know how behavior files work, nor do you need to change your IE CSS coding habits, you just need to download the most recent file and save it to your server (remember to save it with a .htc extension) then call it using the appropriate relative path, from your IE CSS file if/when required. (I keep it in the same root folder as my CSS files for ease.)
Structuring the HTML Code
Building Menus, navigation lists, with nested, unordered lists is widely thought to be one of the most accessible ways to create a menu because it still displays in a logical hierarchy even when CSS is not present, therefore still makes "semantic" sense to text browsers and screenreaders or people who just have CSS turned off in their browsers for whatever reason.
For this reason these example menus are built using unordered lists -
<ul> elements. Correct HTML coding of these nested
<ul>'s is the first bit to get right. if your HTML is not "valid" or at the very least elements are not nested/closed properly then even following the CSS recommendations may not produce the desired results.
<li> element is defined as neither a block element nor an inline element, it is defined as a Flow element.
This simply means it can contain both block and inline elements. In this case that means we can put our
<h2> element and it's corresponding sub levels ~ nested
<ul>'s ~ inside one
This then means we can not only still use semantically correct headings for our lists but by putting them inside an
<li> element we can then overcome IE's lack of support for Child Selectors as mentioned above.
This and keeping the lists seperate becomes more important in the horizontal version of these menus.
The vertical version in SEO Consultants demonstration did not require this and has been built without the same HTML, but if you wanted to code your HTML not knowing whether you wanted horizontal or vertical choices you would build it with seperate lists and the
<h2> nested because both versions can then be styled differently later from the same HTML.
I demonstrate the method used for both versions using one HTML source in the tutorial.
Sample HTML code
1. <ul> 2. <li><h2>CSS Drop Down Menus</h2> 3. <ul> 4. <li><a href="#">CSS Hover Navigation</a></li> 5. <li><a href="#">Example Vertical Pop Out Menu</a></li> 6. <li><a href="#">Example Horizontal Drop & Pop Menu</a></li> 7. </ul> 8. </li> 9. </ul>
The HTML code snippet above shows the
<h2> nested inside the first
<li> element (line 2.) that
<li> is then Not Closed as the entire first sublevel, nested
<ul> is also inside it
(lines 3-7). Then the First Level
<li> is closed (line 8.) and finally the First level
<ul> is closed (line 9.)
If you want to start creating more levels (nesting lists) you nest an entire UL element *inside* an exisiting LI element
To the CSS Tutorial!
This first sample page contains the HTML I will be using for both Horizontal and Vertical sample menus and shows what the unstyled lists looks like.
The whole menu code is wrapped in
<div id="menu"> to seperately IDentify it on the pages and to "contain" them when necessary.
Thank You and Enjoy!
Finally, I strongly recommend you start at the beginning by reading the section covering the vertical menu first, because there is a lot more description in there and a lot of it applies to the horizontal version too, so I didn't bother repeating myself. Now what you waiting for? >> Grab the Code, and Go read the tutorial.
- whatever:hover - Peter Nederlof's behavior file (HTC) which encourages IE to support
- dynamic :hover pseudo-class - CSS2.1 - Dynamic Pseudo-Classes
- Child Selectors - CSS2.1 Recommendations for Child Selectors
- Microsoft Conditional Comments
- HTML Components (HTCs) - for IE - Microsoft's documentation