Multi-level menu with CSS

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.

This entry was posted in by Gabriele Romanato. Bookmark the permalink.

Leave a Reply

Note: Only a member of this blog may post a comment.