CSS Tricks: Navigation

Horizontal and vertical menus without cumbersome LI abuse.

CSS

In this section, I will attempt to document and demonstrate how to overcome some of the little problems that many developers encounter while transitioning from transitional to strict doctypes.

How to Make Reliable, Friendly Navigation

Designers are always trying to create clever navigation systems—drop-down, slide-out, collapsing, etc—and users are always resenting them for it. I’ve never met a client, nor any web user, who wants to repeatedly chase expanding & collapsing, appearing & disappearing menus with their mouse. So let’s all resent such menus together, and make menus that people like to use.

There is nothing backward, deprecated, nor wrong with a simple horizontal or vertical list of links. Here are some rules that users like:

Horizontal Menu

Note: Examples of these menus may be seen in the Table Example page.

This menu example will run the width of the fluid page, just under the header table, with decorative effects. The menu bar is inset, has a background, and the links are CSS “buttons” with a mouseover effect using inset/outset border. Notes:

table.lay { /* our usual fluid layout table */
border-collapse:collapse; width:100%; margin:0; border:0; }

#topmenu { /* the td the links are in */
width:100%; height:24px; margin:0; padding:0;
border:#E2DCC7 1px inset;
background:url('img/paper2-24.jpg') repeat-x scroll left top;
font-family:"Century Gothic",futura,"URW Gothic L",sans-serif;
font-size:12px; font-weight:bold; text-align:center; }

#topmenu p { margin:2px 0 0 0; } /* scoot them down a bit */

#topmenu a { /* define the links as buttons */
margin:0 2px 0 2px; padding:0px 5px 1px 5px;
background-color:#F0E8D7; border:#FFFFFF 1px outset;
text-decoration:none; }

/* no need to repeat all that in a pseudo, just the diffs: */
#topmenu a:hover {
border:#FFFFFF 1px inset; background-color:#E2DCC7; }

The HTML to create the menu bar is even simpler. The td’s contents may be strung out on one line, if you prefer, and in fact must be so if you don’t want an extra space between buttons.

<!-- Top menu -->
<table class="lay">
<tr>
 <td id="topmenu">
  <p>
  <a href="link1.asp">Link 1</a>
  <a href="link2.asp">Link 2</a>
  <a href="link3.asp">Link 3</a>
  </p>
 </td>
</tr>
</table>
<!-- No LI Abuse! -->

Vertical Menu

This is just a little different, in that it uses display:block and sets width on the link buttons, to make them fit the column and look nice. The purpose of the btn class is so we can put other kinds of links in the left column, like an RSS graphic or inline links in the News area.

#lft { /* our usual left-column td def */
border:0; width:175px; min-width:175px; padding:20px;
background-color:transparent; font-size:0.9em;}

#lft a.btn {
display:block; width:100%; text-align:center;
text-decoration:none; font-weight:bold;
font-family:"Century Gothic",futura,"URW Gothic L",sans-serif;
border:1px outset #E2DCC7; background:#F0E8D7;
margin:0 0 5px 0; padding:1px 2px 2px 2px; }

#lft a.btn:hover {
border:1px inset #E2DCC7; background:#E2DCC7; }

The HTML is even simpler than the last example, because, being in the existing left column of the existing content table, all we need is an optional heading, and the links. Also, we don’t need to contain the anchors in a P, UL/LI, or any other tag, because they are display:block elements and will arrange themselves vertically.

<!-- within our left td -->
<h1>CSS Menu</h1>
<a class="btn" href="link1.asp">Link 1</a>
<a class="btn" href="link2.asp">Link 2</a>
<a class="btn" href="link3.asp">Link 3</a>

So there you have it. Once again, there is no messy, deprecated table markup, and (even better) no messy, fussy, floated DIVs, ULs, or LIs. Use the third alternative: CSS-controlled tables. They just work!

— KV5R is disabled. Please help. —

Valid HTML 5 Valid CSS WCAG 1 conformance Handmade with Ultra Edit Studio Xara Xtreme