“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 ; for this example we will stick to a “pop-down” variant that uses only simple CSS, and leave advanced examples for later.

If you have seen other examples of interfaces on this blog, the basic markup for our menu should appear very familiar:

<ul id="nav">
	<li>
		<a href="#">Home</a>
	<li class="multi">
		<a href="#">Our Products</a>
	<li>
		<a href="#">Contact</a>
	<li>
		<a href="#">Privacy Statement</a>
</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; 
	padding-left: 0;
}
ul#nav li a { 
	color: #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 to indicate that multi contains more information:

ul#nav li.multi::before {
	content: "\25B6"; 
	color: red; 
	float: left; 
	margin: .5em; 
}

We also want to change the appearance of the <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 color, 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 by implication; a common mistake is to place the new list after a closing tag, 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 class="multi">
		<a href="#">Our Products</a>
		<ul>
			<li><a href="#">Widgets</a>
			<li><a href="#">Bidgets</a>
			<li><a href="#">Bobs</a>
		</ul>
	<li>
		<a href="#">Contact</a>
	<li>
		<a href="#">Privacy Statement</a>
</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;
}

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.