demosthenes.info

I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

web developer guide

my books

Book cover of Pro CSS3 AnimationPro CSS3 Animation, Apress, 2013

my projects

CSSslidy: an auto-generated #RWD image slider. 1.5K of JS, no JQuery. Drop in images, add a line of CSS. Done.

tipster.ioAutomatically provides local tipping customs and percentages for services anywhere.

Hierarchical Navigation: Accordion Menu

css / navigation

Estimated reading time: 2 minutes, 25 seconds

“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 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 :

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 from the lesson on making decorated horizontal menus 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; }
comments powered by Disqus

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.