Why use entities rather than images?

Speed

The above buttons do not use any image, automatically there's no extra HTTP image request. No image to load means faster rendering.

Scalability

You just need to change the font-size value from the following shorthand declaration:

font:bold1em/2emArial,Helvetica;

There you go, you've just increased/decreased the button's size!

Rendering & browsers support

The icons are added using the :beforepseudo-element. Therefore, you won't see any icons in browsers like IE7 and below, but the buttons will look good yet.

Different operating systems and different browsers means different rendering for the HTML entities we used as icons. If you want to use another icons instead, you could try something like Pictos.

Screenshots made using latest versions for the modern browsers and Windows 7 as OS.

Screenshot made using an iPhone 3GS.

Update

You asked it and now you have it! I added support for the button, input type="button" and input type="submit" elements. Additionally, now they can be disabled by adding the HTML disabled attribute or by adding CSS .disabled class.

A word on inputs spacing

Firefox has taken a decision to limit line-height on buttons as they have defined something like that:

line-height:normal!important;

Also, Opera does exactly the same thing. The thing is that browser-defined !important rules cannot be over-ruled by author-defined !important rules. Automatically there's nothing we can do about line-height.

So, the solution I found is to use some padding for Mozilla Firefox specifically and just leave Opera alone for now. Apparently, the inputs and buttons look as they should only for versions greater than Firefox 5.

Also, Roger Johansson has a potential solution for this matter, but does not quite match for our example.

Inputs and CSS generated content

Using pseudo-elements like :before and :after helps you specifying which content should be inserted before (or after) the content of that element. The input elements have no content, therefore, in our example the :before will not render any icon for the input elements.

Yet, on Opera 11.51 this worked!!! On Opera, if you use CSS generated content for inputs, it works! Strange, huh? :)

Another update

Just added some color to the buttons. To make them even more useful, I chose to create Twitter and Facebook buttons:

I hope you like them, the same technique as above is used. View the demo page source for the styles.

That's all!

I hope you enjoyed this tutorial! Looking forward for your feedback, feel free to add your comment. Thanks for reading!