Pure CSS Dropdown Menus, take II

This article was first published on tjkdesign.com (03-19-2007).

Years ago, I wrote an article about creating horizontal CSS dropdown menus. This menu didn’t look nice but it worked very well across browsers. I also believe it was the first one to address an issue related to links hidden by the CSS "position" property. As with most menus relying on this technique, such links were not revealed through tabbing navigation.

At the time, the real challenge was not to deal, as many might think, with early versions of Internet Explorer, but with Netscape 6 (that menu did work in NN 6.)

Today, Netscape 6 is "dead" and I’m a member of GAWDS. So I thought I could do better in terms of "the look" (no more NN 6) and also in addressing usability/accessibility issues related to Dropdown menus (trying to minimize the problems at hand).

Taking a look at both of these menus should help you see by yourself what’s really involved:

Horizontal sub-menus using the position property:
All links are "exposed"; there are more links to tab through.
Vertical sub-menus using the display property:
More "keyboard-friendly"; there are less links to tab through.

Graceful degradation

With Javascript ON
There is no visual degradation across browsers. The menus look and behave the same (in IE 5 Mac, sub-menus are displayed vertically in both versions).
Wih Javascript OFF
In Internet Explorer versions 5 and 6
Top level list items become clickable and users can navigate from page to page. Sub-menus are horizontally displayed on each page, hence fully accessible.
In modern browsers
Pointing device users have the exact same experience with or without Javascript. Read "the irony" to find out about tabbing navigation.
With Styles OFF
The semantic markup of the menu makes it display as a tree Menu.

Tabbing Navigation

For a few reasons, the vertical version of this dropdown menu is more keyboard-friendly than its horizontal counterpart. With the former, keyboard users are able to navigate from one top level item to the next without having to tab through nested links. The enter key allows them to toggle (show/hide) the sub-menus.

But in modern browsers without script support sub-menus are not accessible. Read “the irony”, and “removing the pure in pure CSS menus” to find out why you should care and what you should do.

The irony

In modern browsers, sub-menus “respond” to the CSS pseudo-class :hover; they “show” when users hover their cursor over a top level list item. Because Javascript is not needed for this “behavior” to work, one could say that this solution improves accessibility. But that assumption would be wrong!

With Javascript OFF, our pure CSS solution cannot reveal sub-menus when keyboard users reach the top items. This is not acceptable. I believe it is better to go with the fail-safe philosophy used for Internet Explorer, in which script support is not an issue (see what’s plan B for Internet Explorer.)

Now, if there is no script support, we make sure the links in the current sub-menu (one per document) are exposed to screen-readers and search-engines.
The only “drawback” of this method is that keyboard-users can’t skip links inside the current sub-menu
.

Removing the pure in pure CSS menus

If you prefer how the menu behaves in Internet Explorer without script support and want the same “look” in all browsers (except IE 5 Mac), then follow these two steps:

  1. Let modern browsers peek at the "TJK_keyBoardDropDownJSoff.css" stylesheet.
    To do so, simply move the following code block from the head section to the body element and remove the Conditional Comment (first and last line).
    <!--[if lt IE 7]>
    <noscript>
    <style type="text/css" media="screen">
    @import "TJK_keyboardDropDownJSoff.css";
    </style>
    </noscript>
    <![endif]-->
  2. Comment or remove the following line from "TJK_keyBoardDropDown.css":
    #TJK_dropDownMenu li:hover ul,

About validation

noscript element
noscript is not allowed in the head element. If it passes validation, it is because it is inside a Conditional Comment.
style element
style is not allowed in the body element so "downgrading" this menu to make it more accessible will invalidate the document.

The case of Safari

I’m used to doing my testing with the oldest browser versions I have; my thinking is that if I can make it work in old versions, it should work in newer ones as well. Unfortunately, when working with CSS, there are no rules (pun intented).

It is Michael from Valley Web Designs who spotted a strange behavior in Safari 2.0.4., something that did not exist in version 1.3.

In version 2.0 - following a certain path - it was possible to keep sub-menus opened while moving from one to another [see test case]. If I say “it was possible”, it is because I found a workaround (reversing the stack order using “z-index”).

It is not a perfect fix though, because it takes care of all sub-menus but the last one. If you use Safari v 2.0 you can experience the bug by hovering over the last sub-menu and going back up to the previous top level item (“articles: P-S”). An easy way to avoid this would be to style this last sub-menu as the others (no negative margin), but I think this is a minor issue and I believe this bug won’t come with future versions of Safari.