In a modern web application we don’t really use buttons (ala the input tag) so much. More often than not, we use some kind of div or link that when combined with some javascript behaves as a button. I’m not going to cover how to hook this all up into your application, but rather just the styling of buttons.
Problem
Traditionally, web developers have had to create graphics for every non-standard button they used on their site. This is expensive in terms of time, money, and usability. It takes extra work for our buttons to be assessable, increases load times, and if we ever want to change the wording of our button, we have to start all over again.
Using various features afforded in css3, we can remove the need for images altogether, lower load times (and save bandwidth) while gaining scalability of our user interface, full accessibility, and never have something that is completely reusable throughout our site without any extra work.
We are going to go from the one on the left to the one on the right.

Solution
First, we need to begin with our basic markup.
<a href="#">My Button</a>

Because we want to style it and reuse said styles more than once on a page (potentially), we’re going to want to add a css class name.
<a href="#" class="gradient_button">My Button</a>
That’s all the html markup we will use. From here on out, we will just be adding styles to our stylesheet. The first thing we need to do is decide which color our button needs to be. We need a minimum of 2 colors: one lighter color for the top of the button and one darker color (of the same shade) for the button of the button.
I used the CSS3 Gradient Generator to select my colors and generate the rules. I’ve picked a grey color for this tutorial. Feel free to pick anything you like. Let’s set it as the background for our button. Let’s create our gradient_button selector and add our gradient background
a.gradient_button { background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0.43, rgb(237,234,237)),color-stop(0.72, rgb(176,176,176))); background-image: -moz-linear-gradient(center top,rgb(237,234,237) 43%,rgb(176,176,176) 72%); }

It’s ugly, but we’re getting closer. Next, let’s add some padding around our button, create a border, and give it rounded corners. Add the following to the gradient_button selector.
border:solid 1px #111; -webkit-border-radius:3px; -moz-border-radius:3px; padding:5px;

Already we are looking much better and more realistic. However, the text completely throws the button off. It looks like it’s just pasted on there. We want our text to be a part of the button. We can do that by insetting the text with a shadow. So, next, let’s remove the text decoration, change the color, and inset that text.
color:#111; font-weight: bold; text-shadow:#ffe 0px 1px 0, #333 0 -1px 0; text-decoration: none;

Already, you can see our button finally looks like a button. We could stop there, but we should go the extra mile for that last bit of polish. Especially considering how much time we can save because we never have to visit photoshop to make a button again.
First, we need to recognize that objects are never flat. Everything casts a shadow. Our buttons are no different. Remember to try and keep a consistent light source when implementing shadows on your website, my light source is directly above, so I only want to cast a shadow below my button. Add the following to the selector:
-moz-box-shadow: 0px 2px 5px #999; -webkit-box-shadow: 0px 2px 5px #999; box-shadow: 0px 2px 5px #999;

Our button now looks great. Try clicking on it. Notice that? It maybe look like a button, but it surely doesn’t behave like a button. We can fix that by adding one more selector. We need to style the :active state of the link, which is displayed when a button is pressed.
When picturing a physical button pressed, what sort of changes we see? I imagine that the shadow would disappear, as the button is now becoming flat with the surface from which it protrudes. Also, I imagine that the shine of our gradient would change. I think that it would become almost a solid color, but not quite. Let’s one last style to make our button behave a lot more naturally when clicked.
a:active.gradient_button { -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow:none; background-image: -webkit-gradient(linear,left bottom,left top,color-stop(0.18, rgb(237,234,237)),color-stop(0.59, rgb(176,176,176)),color-stop(0.8, rgb(237,234,237))); background-image: -moz-linear-gradient(center bottom, rgb(237,234,237) 18%,rgb(176,176,176) 59%,rgb(237,234,237) 80%); }

There we have it. A completely realistic button using nothing but CSS3 and a hyperlink.
Conclusion
CSS3 buttons allows us to save time (and therefore money) when developing a modern web application. Moreover, we get fringe benefits such as being able to make our website more accessible and fully scalable for free.
Update:
This doesn’t work in IE. If you’d like to use a similar effect for the gradient, you can use the IE filter styles. The major caveat is that IE only seems to render these with a div wrapper or an absolute position. The div wrapper really kills the elegance of being able to have any link suddenly look and behave like a regular button with a single style. I recommend a graceful-degradation in IE, and just set the background color to a be solid.
The css for getting the same gradient effect in IE is as follows:
/* For Internet Explorer 5.5 - 7 */ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#EDEAED, endColorstr=#B0B0B0); /* For Internet Explorer 8 */ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#EDEAED, endColorstr=#B0B0B0)"; /* graceful-degradation when the filter doesn't work */ background:#EDEAED;


Works and looks fantastic in firefox. Too bad Internet Explorer can’t get with the program. IE8 displays it as bolded text within a rectangular outline. sigh
@Lauren I think one could easily add support for IE by using a IE only extentions. Something like the following:
I haven’t tested it (just found this online in a quick google search).