Graphic Looking Buttons in CSS without Javascript and images

We'll use a standard UL containing links to create a dynamic menu with hover effects. In order to obtain the hover effects we'll let the UL provide the structure, and the anchor styles will provide most of the visual effects.

This menu of links is actually a solution to a question posed by Michael Efford on the css-discuss list. Michael had created this exact effect using a table, images, and JavaScript. He asked the list if it could be done with CSS. I took the challenge, and with the help of several other members who tracked down some browser specific issues, we came up with a style sheet that works on this markup:

<div id="button">
<ul>
	<li><a href="#">Home</a></li>
	<li><a href="#">Hidden Cameras</a></li>
	<li><a href="#">CCTV Cameras</a></li>
	<li><a href="#">Employee Theft</a></li>
	<li><a href="#">Helpful Hints</a></li>
	<li><a href="#">F.A.Q</a></li>
	<li><a href="#">About Us</a></li>
	<li><a href="#">Contact Us</a></li>
</ul>
</div>

Let’s look at the style sheet rule by rule, and I'll explain why each rule is constructed the way that it is.

#button {
	width: 12em;
	border-right: 1px solid #000;
	padding: 0 0 1em 0;
	margin-bottom: 1em;
	font-family: 'Trebuchet MS', 'Lucida Grande',
	  Verdana, Lucida, Geneva, Helvetica, 
	  Arial, sans-serif;
	background-color: #90bade;
	color: #333;
	}

The first rule is for the #button DIV. It defines the space that the menu will occupy, and provides a context for the menu so that we can define the way the list and links will behave inside the DIV. I chose to make the menu fluid, based on the browser’s font size preferences, so (almost) all units are in ems. This includes the width of the menu. The solid black border on the right was based on the original design from Michael. The bottom padding is there to extend the DIV down beyond the menu of links so that you can see the background of the DIV. Again, this follows the original design. The bottom margin is to separate the DIV from what follows it. The colors came from the original design.

	#button ul {
		list-style: none;
		margin: 0;
		padding: 0;
		border: none;
		}
		
	#button li {
		border-bottom: 1px solid #90bade;
		margin: 0;
		}

Next I defined what the list will look like. Since all the list items were to be links, and the rollover functionality would be built into the CSS for the links, I essentially removed all styling from the lists. I did add a single pixel border on the bottom of each link that matched the background of the #button DIV, to work as the separator. In the original design, this was an image.

	#button li a {
		display: block;
		padding: 5px 5px 5px 0.5em;
		border-left: 10px solid #1958b7;
		border-right: 10px solid #508fc4;
		background-color: #2175bc;
		color: #fff;
		text-decoration: none;
		width: 100%;
		}

	html>body #button li a {
		width: auto;
		}

	#button li a:hover {
		border-left: 10px solid #1c64d1;
		border-right: 10px solid #5ba3e0;
		background-color: #2586d7;
		color: #fff;
		}

Finally, I defined the links. The original design has 10 pixel borders on the right and left. These borders, along with the background, change color on the rollover. This is a relatively simple thing to control with the :hover pseudo-class in CSS, so I put this style into the anchor styles.

There is one workaround in this part of the style sheet. To make the links active for the full width of the DIV, I made them display: block;. This works for everything but IE/Windows. If you give the block an explicit width of 100%, then IE/Windows plays along. But doing this creates problems with IE5/Mac and Netscape/Mozilla. So I used the child selector“>” to redefine the width to auto. Since IE/Windows doesn’t understand child selectors, it ignores the rule. IE5/Mac, Opera and Netscape/Mozilla follow the rule, and everyone is happy.

The rule for the :hover pseudo-class creates the color changes on the backgrounds and borders when the links are moused over.

The style and list markup (about 1K worth) replaced about 5K of JavaScript and TABLE markup, not to mention another 8K or so of images for the rollover effects. It also made the markup more readable, and easier to update, since you no longer need to create new images if a link name changes. Now you simply modify some text. You can view the final result in the context of the site on the Asset Surveillance web site.

 

*Mark Newhouse: http://www.alistapart.com/stories/taminglists/index.html