Publishers of technology books, eBooks, and videos for creative people

Home > Articles > Web Design & Development > Usability

Web Design Reference Guide

Hosted by

How to Create CSS Menus

Last updated Oct 17, 2003.

This section will help explain how you can chuck images from menus or combine them with CSS to create clean and fast loading navigational items without a drop of JavaScript. Gecko and Safari-based browsers correctly display them. Opera has minor issues, but all the examples work fine. As for the elusive IE, it won't show the drop down items in the last example. However, IE displays all the other menus A-OK, except the first one loses its top and bottom borders.

Suckerfish Dropdowns at A List Apart explains how to create a standards-compliant, cross-browser menu. See the example, which works perfectly in IE as it works around IE's inability to handle the :hover pseudo class. The workaround requires adding JavaScript. I can see some of you pulling your hair out in frustration with cross-browser issues.

Take some aspirin because this is not the end of the problems with implementing pure CSS menus. An Evolt article describes the problems of using pure CSS menus, which leads to mouse-dependency. Could there be an MA organization? Mouse Anonymous? Back to the point. Tabbing doesn't work consistently across browsers, and accesskeys are not an option for users who don't typically use them — they wouldn't know what keys to use. No standards exist for accesskeys.

Another note: the drop-down menu is purely for teaching purposes. I don't encourage them nor fly-outs or any submenu spilling guts approaches. They're hard on the eyes and the hands. How often have you been on a drop-down menu only to lose your place and the dropdown menu disappears? Furthermore, users might think, "I worked hard to make a decision to go to this menu item, and now I have to make another decision before I can go anywhere?" If you must have drop-drown, fly-out thingies, at very least, make the main menu item clickable.

I don't claim to be an artist, so don't expect beautiful menus like those you see in CSS Zen Garden or at many talented designers' sites. The steps here should help anyone new to CSS and using it for navigation.

Examples

The first four menus all use the same markup. The difference is in the CSS recipe. No fancy stuff. Study the CSS and see how each turns out differently. The instructions for what happens in the CSS are in the comments between /* and */.

<div id="menu">
<ul>
<li><a href="#">Item 1</a></li>
<li><a href="#">Item 2</a></li>
<li><a href="#">Item 3</a></li>
<li><a href="#">Item 4</a></li>
</ul>
</div>

And this is how they look when they're not stylin'.

EDITOR'S NOTE

The following links won't work; they're just examples. I figure you're smart enough to understand that, but just in case you were about to send an email to inform us we had some bad links, save your time. We do this again later on the page.

Menu 1 has four items and each changes during hover.

#menu1 ul {
	list-style: none;     /* turns off bullets */									
	margin:5px;                /* adds margin of 5 to all sides */
	padding:5px; 
	font-size:1em;             /* kinda easy to figure out */
}
#menu1 {
	margin: 16px 0 2.5em 0;     /* width of box outside of border (top, right, bottom, left - remember by acronym TRouBLe */
	width: 100%;                /* amount of width to use */
      font-weight:bold;
}
#menu1 li {
	float: left;
	list-style: none;     /* turns off bullets */
	margin-bottom: 1em;        /* adds margin on bottom */
	padding: 2px;              /* adds padding on all sides */
}
#menu1 a {
	padding: 5px 20px;         /* top & bottom = 5px, right & left = 20 */
	border: 1px solid #ccc;    /* puts a 1 px solid lt gray border around box */
	background-color: #fff;    /* box background color is white */
	text-decoration: none;     /* no underlining of links */
}
#menu1 a:link, #menu1 a:visited {
	color: #ccc;              /* lt gray text for visited links */
}
#menu1 a:hover {
	background-color: #000;   /* black background for hovered items */
	color: #fff;              /* white text for hovered items */
}

The results in Mozilla, Opera, and Internet Explorer are in Figure 1 below.

Figure 1aFigure 1a Mozilla




Figure 1bFigure 1b Opera




Figure 1cFigure 1c Internet Explorer




For Menu 2, the navigation is vertical instead of horizontal with the same effects as Menu 1.

#menu2 ul {
	list-style: none;         /* turns off bullets */
	margin:5px;               /* adds margin on all sides */
	padding:5px;              /* keeps navigation from being flush against left side */
	font-size:1em;
}
#menu2 a:link {
	display:block;            /* makes area clickable */			
	margin:3px 0;             /* top & bottom = 3px, right & left = 0 */
	padding:5px 0;            /* top & bottom = 5px, right & left = 0 */
	background:#ccc;          /* box background is lt gray */
	color:#ff3;               /* text in box is yellow */
	text-decoration: none;    /* no underlining of links */
	text-indent:25px;         /* keeps text from being flushed on left side */
	font-family: Verdana, arial, sans-serif;									
	font-weight:bold;
	width:100px;              /* width of navigation bar */
}
#menu2 a:visited {
	display:block;            /* makes area clickable */
	margin:3px 0;             /* top & bottom = 3px, right & left = 0 */
	padding:5px 0;            /* top & bottom = 5px, right & left = 0 */
	background:#ccc;          /* box background is lt gray */
	color:#999;               /* text in box is dk gray */
	text-decoration: none;    /* no underlining of links */
	text-indent:25px;         /* keeps text from being flushed on left side */
	font-family: Verdana, arial, sans-serif;
	font-weight:bold;
	width:100px;              /* width of navigation bar */
}
#menu2 a:hover{                 /* changes hover background and font color */
	background:#36f; 
	font-weight:bold;
	color:#ff3
}

The results in Mozilla, Opera, and Internet Explorer are in Figure 2 below.

Figure 2aFigure 2a Mozilla






Figure 2bFigure 2b Opera







Figure 2cFigure 2c Internet Explorer







Time to play with images. In Menu 3, two images are used along with CSS for positioning and the a element.

#menu3 ul {             /* based on earlier examples, can you figure out what this does? */
	list-style: none;
	margin:5px; 
	padding:5px; 
	font-size:1em;
	font-weight:bold;
}
#menu3 li {
	margin:0px;                /*no space between list items*/
}
#menu3 a {
	display:block;                 /* clickable area */
	width: 100px;                  /* size of clickable area: block */
	padding:0.6em 0.6em 0.6em 3.5em;   /* space between border and text */
	background-image: url(down.gif);   /* bring on the image */
	background-repeat:no-repeat;       /* show the image once not endless times */

/* next: pair of '0 0', the upper left corner of the image is aligned with the upper left corner of the box's padding edge. We place it in the left corner, half-way down the padding area. */

	background-position:0 50%;																/** we don't need to declare units on zero values (i.e say 0 not 0%). we can also use key word alternatives: left center */ 
	text-decoration:none;
	color:#30c;                       /* color that closely matches image */
}
#menu3 a:hover, #menu3 a:active {
	background-image:url(over.gif);   /* the 'rollover' image */
	background-repeat:no-repeat;      /* show the image once not endless times */
	background-position:0% 50%;       /* see previous long explanation */
	color:#fc0;                       /* color that closely matches image */
}

The results in Mozilla, Opera, and Internet Explorer are shown in Figure 3 below.

Figure 3aFigure 3a Mozilla







Figure 3bFigure 3b Opera








Figure 3cFigure 3c Internet Explorer











Use different images this time and lay them straight for the next example.

#menu4 ul {                       /* Can you figure out menu4's CSS? It's similar to menu3 */
	list-style: none;     
	margin:5px;               
	padding:5px;       
	font-size:1em;
}
#menu4 {
	margin: 16px 0 2.5em 0;
	width: 100%;
	font-weight:bold;
}
#menu4 li {               /* This time we use float to get a horizontal effect. It may be better to float all 
  • and set a width on the containing element in all these examples to eliminate IE's white-space bug. */ float: left; list-style: none; margin-bottom: 1em; padding: 2px; } #menu4 a { display: block; padding:0.6em 0.6em 0.6em 2em; background-image: url(down1.gif); background-repeat:no-repeat; /* FYI - shorthand syntax: background: transparent url(down1.gif) no-repeat 0 50%; */ background-position:0% 50%; text-decoration: none; color:#fff; } #menu4 a:hover, #menu4 a:active { background-image:url(over1.gif); background-repeat:no-repeat; background-position:0% 50%; color:#ff0; }
  • The results in Mozilla, Opera, and Internet Explorer are seen in Figure 4 below.

    Figure 4aFigure 4a Mozilla




    Figure 4bFigure 4b Opera




    Figure 4cFigure 4c Internet Explorer




    Menu 5, a la drop-down, lookes like a monster, but it's a little giant (oxymoron, I know). It requires only two additional items not in the other menus:

    1. Another set of bullets because of the submenus.
    2. An "li" class for each menu item.

    That isn't so bad after all. CSS takes care of the rest. The submenus needs its own class to distinguish it from the main menu items for the a element. See what happens if you remove .menuitem5 and rely on just menu5 for the menu by stripping the class.

    <ul id="menu5">
    <li class="menuitem5" id="item1"><a href="#">Item 1</a>
    <ul>
    <li><a href="#">Subitem A</a></li>
    <li><a href="#">Subitem B</a></li>
    <li><a href="#">Subitem C</a></li>
    <li><a href="#">Subitem D</a></li>
    </ul>
    </li>
    <li class="menuitem5" id="item2"><a href="#">Item 2</a>
    <ul>
    <li><a href="#">Subitem A</a></li>
    <li><a href="#">Subitem B</a></li>
    <li><a href="#">Subitem C</a></li>
    <li><a href="#">Subitem D</a></li>
    </ul>
    </li>
    <li class="menuitem5" id="item3"><a href="#">Item 3</a>
    <ul>
    <li><a href="#">Subitem A</a></li>
    <li><a href="#">Subitem B</a></li>
    <li><a href="#">Subitem C</a></li>
    <li><a href="#">Subitem D</a></li>
    </ul>
    </li>
    <li class="menuitem5" id="item4"><a href="#">Item 4</a>
    <ul>
    <li><a href="#">Subitem A</a></li>
    <li><a href="#">Subitem B</a></li>
    <li><a href="#">Subitem C</a></li>
    <li><a href="#">Subitem D</a></li>
    </ul>
    </li>
    </ul>

    And its plain Jane look:

    And so we add some style with CSS...

    #menu5 ul, #menu5 li {
    	display:block;
    	list-style: none;
    	margin:0;
    	padding:0;
    }
    
    #menu5 li {
    	float: left;
    	width: 10em;
    }
    
    #menu5 li ul {
    	display: none;
    }
    
    #menu5 li:hover ul {
    	display: block;
    }
    
    #menu5 li ul li {
    	display: block;
    	float: none;
    }
    
    .menuitem5 a {
    	background-color: #fff;
    	border: 1px solid #ccc;
    	display: block;
    	text-decoration: none;
    	color: #999;
    }
    
    .menuitem5 ul a { 
    	background: #ccc;      /* gives inactive items a lt gray background */
    	color: #fff;           /* gives inactive items a lt gray text */
    }
    .menuitem5 a:hover {
    	background-color: #999;    /* gives hover items a dk gray background */
    	color: #fff;               /* makes the hover items white text */ 
    }

    To get the big finish in Mozilla, Opera, and Internet Explorer, see Figure 5 below. (menu5moz, menu5opera, menu5ie.gif).

    Figure 5aFigure 5a Mozilla




    Figure 5bFigure 5b Opera




    Figure 5cFigure 5c Internet Explorer




    Get the graphics used in the above menus here:

    down.gif

    down1.gif

    over.gif

    over1.gif

    Resources for more goodies:

    e-lusion free menu designs

    Eric Meyer's Pure CSS Menus

    Max Design Listutorial

    Mezzoblue's MOSe menus

    Peterned whatever:Hover

    Stu Nicholls

    Flowing a list across multiple columns

    Web Page Design for Designers

    Thanks to Terrence Wood, Ethan Marcotte, and Chris Heilmann for their contributions.