If you want a carbon copy of everyone else’s buttons, with a thin border, slightly rounded corners, and a gradient/inset shadow creating a slight rounding effect, CSS is OK.
However, as soon as you want anything more distinctive, you run into cross-browser problems almost immediately. IE9 doesn’t support CSS text-shadow and gradients. IE8 and below don’t support rounded corners or shadows either, and they seem to have problems using the full range of weights available with some popular web fonts, too.
Even with a bleeding edge version of Chrome or Firefox, there are only so many effects you can generate with styles alone, and even then the results of fine-tuned visual effects generated by Photoshop are often visibly superior to a limited version of the same effects applied using CSS.
In other words, there is still no browser available today whose rendering engine can compete with one of the heavyweight professional graphics applications. That’s hardly surprising, yet if you read all the trendy design blogs you’d think it was crazy talk! :-)
The thing that really swung it for us, though, was that most of the advantages of using only HTML and CSS turned out to be illusory anyway, at least for our site.
We do have to create a separate button for each label we want to use instead of just changing the text in HTML, but that takes only a few seconds with Photoshop. As I noted above, we spent half a day experimenting with button styles using CSS and never found anything satisfactory across the full range of browsers we have to support.
Having plain text in the HTML might seem better semantically, but it’s unlikely that we actually care about button labels for SEO purposes, and we still have all the same image accessibility hints available as we always did.
The image file size and number of requests might be important concerns in some applications, but if you’ve only got a couple of buttons on a page, it’s unlikely to make any perceptible difference to performance. They might even be smaller than trying to encode all the cross-browser styling information in CSS and/or adding various non-semantic mark-up in the HTML to support it, and that potentially applies whether you download them as separate images or you embed them in the CSS using the data: syntax.
In short, pure CSS buttons seem to have few actual advantages over images and tend to bring a significant loss of quality and distinctiveness in the best browsers and horrible degradation in older but still relevant versions of IE. Unless you actually need to generate the button labels on the fly — and even then, you can still use a background image — I don’t see a good case for moving away from tried-and-tested image-based buttons to a pure CSS approach for most projects.