All About Menus and Buttons

Articles > Webmaster > All About Menus and Buttons

Just about every website needs to have a menu — that ubiquitous row of hyperlinks that helps the user find the page they need. And whether the menu is going to be vertical or horizontal, whether it will look like a collection of tabs or a set of buttons, the basic HTML for the menu should always be the same: an unordered list made with <ul> and <li> tags.

All of the examples that you see on this page (except example 3b) have exactly the same HTML:

<!-- each example uses a different class name -->
<ul class="menu2a">
  <li><a href="#">Home</a></li>
  <li><a href="#">About</a></li>
  <li><a href="#">Products</a></li>
  <li><a href="#">Services</a></li>
</ul> 

The different appearances are all due entirely to different CSS stylings. The most basic styling switches an unordered list from being a series of lines with leading bullets into either a horizontal or vertical row without bullets. We do this by setting the list-style to none and optionally floating the items to the left (note that we could have set display: inline instead of float: left, but that will cause problems when we try to set a fixed width for each menu item).

Example 1a: No Custom Styling (View Code)

 

Example 1b: Vertical Menu (View Code)

 

Example 1c: Horizonal Menu (View Code)

 

Simplest Case: Colored Text, Backgrounds, and Borders

The simplest way to create menu buttons is simply to use CSS to define the colors and borders of your <a> tags. This takes almost no time and the results are not bad:

Example 2a: Color and Borders
(Vertical Menu With Fixed Width)
(View Code)

 

Example 2b: Color and Borders
(Horizontal Menu With Variable Width)
(View Code)

 

Looking Better : Background Images

The next possibility is to create a custom image for your buttons and lay it down underneath the text. We add some top padding to vertically center the text, and set the bottom margin to the same amount (but negative) to compensate. To get the image rollover effect without having to preload the rollover images we use a technique invented by Petr Stanicek — each image is actually two in one (the basic image side-by-side with its rollover) and for the :hover tag we simply shift the image to the left to reveal the second version.

Example 3a: Background Image
(HTML text)
(View Code)

 

The disadvantage of this approach is that our buttons are a fixed size, and so the web page does not respond gracefully if the user enlarges their viewing text (press Control-+ or Apple-+ to see what I mean). One solution is to create a custom image for each button. This resolves the font-resizing issue by not resizing the fonts (since the button labels are now images). We get rid of the old text labels by setting text-indent: 100% and setting overflow: hidden (which pushes them right off the button).

This approach requires slightly different HTML than the rest: we must specify the button's name so that we can set a different image per button. You can use either the id or the class and identify either the <li> or the <a> tag; in this example I set the class of the <li> tag.

Example 3b: Background Image
(image text)
(View Code)

 

Resizable Images: Sliding Doors

That last solution is in many ways my favorite — you never have to deal with font-scaling issues, which means that your menu column can be a fixed width. And that solves all sorts of layout problems. But sometimes you cannot pregenerate the images. Perhaps the web page (including the menu labels) is being generated from a database, or perhaps you must allow the labels to resize as the user enlarges the text. Never fear, Douglas Bowman has created the sliding doors solution. The basic idea here is that we split the button image in half, and use one image as the background of the <li> tag and the other as the background of the <a> tag. You must choose whether the image will be split horizontally (and the menu item will have a fixed width and flexible height) or vertically (and the menu item will have a fixed height and flexible width).

Example 4a: Sliding Doors
(Fixed Width)
(View Code)

 

Example 4b: Sliding Doors
(Fixed Height)
(View Code)