Roger Johansson is one of the best web developers on the WWW. His posts are always seminal and inspirational, particularly those related to front-end languages. A couple of years ago I saw an excellent test page on his website showing a multi-level menu. Today I decided to try to build something similar with CSS and a bit of jQuery. CSS will play the major role, while jQuery will simply add some cosmetic effect. We start with a basic markup like this:
<ul id="navigation"> <li><a href="#">Home</a></li> <li><strong>Articles</strong> <ul> <li><a href="#">CSS</a></li> <li><a href="#">JavaScript</a></li> </ul> </li> <li><a href="#">About</a></li> </ul>
What we got here is a nested sub-menu contained within an upper-level menu item. We want that the selected item show the child list with all its items displayed as inline elements, just below
the strong
element. To accomplish this task, I'll try to use floats and not to position elements. Here's the main CSS:
body { margin: 0; padding: 0; color: #333; background: #fff; font: 76% Verdana, sans-serif; } #navigation { margin: 0; padding: 0; list-style: none; height: 100%; overflow: hidden; font-size: 1.2em; background: #eee; border-bottom: 1px solid #999; } #navigation > li { float: left; margin: 0 0.5em; } #navigation > li > a { float: left; display: block; color: #338; text-decoration: none; padding: 0.3em; font-weight: bold; } #navigation > li > a:hover { color: #00f; } #navigation li strong { display: block; padding: 0.3em; text-transform: uppercase; text-align: center; background: #fff; float: left; cursor: pointer; } #navigation li strong:hover:after { content: ' +'; color: blue; font-size: 1.2em; } #navigation li ul { margin: 0; padding: 0; list-style: none; background: #fff; clear: left; display: none; } #navigation li ul li { display: inline; margin-right: 0.3em; }
Let's break down this code into logical parts: first of all, I used the child selectors just to be sure that only the direct children of the main list were selected. In other words, I did not want
to select the sub-menu and its children. Done this, I've created the horizontal menu only with floats. On the strong
element I've added a pseudo-animation on hover by using CSS
generated content (just a plus sign after the textual content of such element). Of course the secondary menu did not need to be floated, so I've used clearance on it. Finally, I turned all the sub-items
into inline elements to create the effect of a secondary horizontal menu.
jQuery is used only to show the sub-menu when a user clicks on the active element. Basically, this code has the major disadvantage of creating a gap between the active tab and the rest of the navigation menu, especially when there are many sub-items. However, it doesn't use positioning, and that's what I wanted to do. You can see this demo here.