“Accordion” menus are vertically-oriented navigational menus that contain further vertical sub-menus inside them, revealed with a click or a mouse-over on their parent elements. Accordion menus are sometimes animated with JavaScript or CSS3; for this example we will stick to a simple “pop-down” variant that uses only CSS Levels 1 and 2, and leave advanced examples for later.
If you have been following the navigational series on this blog, the basic markup for our menu should appear very familiar:
- <ul id=nav">
- <li><a href="#">Home</a></li>
- <li class="multi"><a href="#">Our Products</a></li>
- <li><a href="#">Contact</a></li>
- <li><a href="#">Privacy Statement</a></li>
- </ul>
The <li> element with the “multi” class will contain our sub-menu, which we will add in a little while. First, let’s add the basic CSS:
- ul#nav { list-style-type: none; width: 12em; background: black;
- font-family: "Helvetica CY", Helvetica, Arial, sans-serif; padding-left: 0; }
- ul#nav li a { colour: #fff; text-decoration: none; font-size: larger;
- line-height: 200%; display: block; border-bottom: 1px solid #777;
- padding-left: 1em; }
- ul#nav li a:hover { background: #633; }
This is very similar to what was used in my previous example of a vertical menu. We’re also going to use a little CSS from the lesson on decorated horizontal menu to indicate that “multi” contains more information:
- ul#nav li.multi::before { content: "\25B6"; colour: red; float: left;
- margin: .5em; }
We also want to change the appearance of the “multi” <li> when the mouse is over it. We will use an unusual combination of two pseudo-selectors - :hover and ::before, in that order – to achieve this:
- ul#nav li.multi:hover::before { content: "\25BC"; }
Note that we do not have to re-state the colour, margin, etc of our Unicode symbol; that is inherited from the previous declaration.
I strongly recommend building the menu to this state and then adding the sub-menu portion, as we do in class, and are about to do so here; proceeding otherwise tends to lead to confusion.
A properly-coded hierarchical menu of most any form is normally a nested list, with sub-menus placed inside an <li> element. Note that this new list has the <li> wrapped around it; a common mistake is to place the new list after the closing </li>, which will not only make the page invalid but also cause the CSS to not render our menu correctly.
- <ul id=nav">
- <li><a href="#">Home</a></li>
- <li class="multi"><a href="#">Our Products</a>
- <ul>
- <li><a href="#">Widgets</a></li>
- <li><a href="#">Bidgets</a></li>
- <li><a href="#">Bobs</a></li>
- </ul>
- </li>
- <li><a href="#">Contact</a></li>
- <li><a href="#">Privacy Statement</a></li>
- </ul>
Also note that the <li> that contains a nested list has a class value of “multi” added to it: this allows us to control the appearance of our sub-navigation elements with greater ease, especially if they appear multiple times. (For the sake of clarity we have only one use of “multi” in this example).
Our sub-menu will inherit the appearance of the rest of the list, but will appear in its “expanded” state and indented from the side (as the browser automatically treats nested lists that way). We want the sub-menu to not be visible by default, and not indented:
- ul#nav li.multi ul {display: none; padding-left: 0; }
- ul#nav li.multi:hover ul { display: block; }
so we don't need the jQuery minimum length anymore:) cool!


