CSS buttons are much more efficient than image-based buttons because they're entirely text-based. A simple unordered list is all you need in the XHTML markup—CSS styles take care of the rest. Furthermore, you don't need any JavaScript to swap images for a rollover effect because CSS pseudoclasses let you build separate styles for each of the states (link, visited, hover, active) of a hyperlink.
The only problem with pure CSS buttons is that they tend to look rather flat with a solid colour background and a simple border. One solution is to use a hybrid technique that incorporates a background image behind the CSS-styled text button to give it a 3D effect. However, reader e-mail prompted me to look for a way to create a 3D button effect with pure CSS—no images required. I found not one, but two, techniques for creating a bevelled-edge look by styling the borders of a CSS button.
Creating a bevelled-edge effect
To give a button a 3D bevelled-edge effect, you need to simulate a light source creating highlights and shadows on the edges of a raised button. If the light source is above and slightly to the left of the button, then the top and left sides of the button will be lighter than the front face, and the bottom and right sides will be darker than the button face.
So, the secret of the three-dimensional effect is to use CSS borders to simulate the sides of the button and to give each border a slightly different colour, depending on whether it represents a highlighted side or a shadowed side. To look realistic, the borders should have mitred corners, and CSS borders meet that requirement nicely.
Technique 1: Using inset/outset borders
As it turns out, there is a CSS border property that is capable of producing a reasonable facsimile of a bevelled edge effect automatically. You don't need to do anything more than specify inset or outset as the border-style attribute for your button styles. The browser handles the details of rendering the element borders in slightly different shades of the background colour to achieve the desired effect. The outset attribute simulates the shaded edges of a raised button and the inset attribute simulates a depressed button by reversing the shading.
Figure A shows the inset/outset border effect at work. This example is produced with some very simple code. The XHTML markup is nothing more than an unordered list containing the button labels and links.
<body>
<div id="buttonA">
<ul>
<li><a href="link1.html">Button 1</a></li>
<li><a href="link2.html">Button 2</a></li>
<li><a href="link3.html">Button 3</a></li>
</ul>
</div>
</body>
The CSS styles that make this technique work are very similar to the styles for a set of plain, flat CSS buttons. The only additions are the border-style: outset and border-style: inset rules combined with a border-width setting that's thick enough to make the effect visible.
body {
margin: 0px;
0px;
}
div#buttonA {
margin-left: 50px;
}
div#buttonA ul {
margin: 0px;
padding: 0px;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 12px;
line-height: 30px;
}
div#buttonA li {
list-style-type: none;
height: 30px;
width: 125px;
margin: 20px;
text-align:center;
}
div#buttonA li a {
height: 100%;
width: 100%;
display: block;
text-decoration: none;
border-width: 6px;
}
div#buttonA li a:link {
color: #000000;
font-weight: bold;
background-color: #CCCCCC;
border-style: outset;
}
div#buttonA li a:visited {
color: #000000;
font-weight: normal;
background-color: #CCCCCC;
border-style: outset;
}
div#buttonA li a:hover {
font-weight: bold;
color: #FFFFFF;
background-color: #999999;
border-style: outset;
}
div#buttonA li a:active {
font-weight: bold;
color: #FFFFFF;
background-color: #666666;
border-style: inset;
}
I've covered the technique for creating CSS buttons in previous articles, so I'll just hit the high points.
The div#buttonA ul rule sets the general text size and spacing, while the div#buttonA li rule removes the default bullet from the list items (list-style-type: none) and sets the size of the button box. The div#buttonA li a rule makes the entire button clickable (height: 100%; width: 100%; display: block;), and it's also a convenient place to set the border thickness (border-width: 6px).
The rest of the styles control the appearance changes for the various button states. For each pseudoclass (:link, :visited, :hover, :active), there is a color, font-weight, background-color, and border-style rule. All the styles use the border-style: outset rule except for the div#buttonA li a:active rule, which includes border-style: inset instead. This gives all the button states a raised appearance—except when the button is clicked, in which case, it looks depressed.
There are significant differences in the way the various browsers render the inset and outset borders. Internet Explorer creates a more subtle effect, with a highlight along the inner edge of each border and shading toward the outer edges. Netscape, on the other hand, renders each border in a solid colour, which produces a sharper, less rounded, look.

Do you need help with CSS? 



1
Jon-Paul LeClair - 23/09/04
Ummm...why not use the "outset" border option?
It generally gets the job done quickly and you don't have to monkey around with coloring all the sides...
border : 2px outset;
then on :active you just use the "inset" option.
However..the :active pseudo class is problematic in IE....
» Report offensive content
2
Toby Mills - 26/09/05
ah, but if you want these buttons to work with a form then you must use javascript which is not accessibility friendly as some people may have Javascript turned off.
Is there any way to do this with buttons on input type="button" i wonder?
» Report offensive content
3
Andrei Sura - 01/12/06
Useful article.
About using this in a form...
I just used this in a form in a different way
Input field is hidden but is available via his label; advantage is that you can use accesskeys.
» Report offensive content
4
slartimitvar - 10/12/06
unfortunately neither of your border effects work on hover for IE7. I'm having the same trouble with my page and haven't yet found a solution other than this one for IE7 hover effects in general through using strict doctype.
http://www.bernzilla.com/item.php?id=762
» Report offensive content
5
JasonC - 15/08/07
One thing I noticed about these buttons is that they need some type of "onmouseout" feature for indecisive users. if you hover over them with the mouse, then left click to select it but do not release the left mouse button and move the cursor off the styled button on the page then they never return to the "unclicked" state like a normal html button element would.
» Report offensive content