Whether you’re designing a website or a web application, you’ll need buttons for it. Now, with CSS3′s help, it was never easier to create nice looking buttons.
In this article you’ll learn how to create some cool CSS3 buttons in just a few steps.

While last time we’ve created simple CSS3 gradient buttons, this time we’ll build some nice CSS3 buttons with icons.
In order to create the icons, this set of CSS3 buttons uses HTML entities. Also, gradients, shadows and many other CSS3 features do not miss.
Minimal markup
<a href="" class="button">Button</a>
Simple button, with no icon.
<a href="" class="button add">Add</a>
Note the add class who adds the plus icon.
CSS
Below you can find the styles used to create the buttons and icons:
.button
{
display: inline-block;
white-space: nowrap;
background-color: #ccc;
background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#ccc));
background-image: -webkit-linear-gradient(top, #eee, #ccc);
background-image: -moz-linear-gradient(top, #eee, #ccc);
background-image: -ms-linear-gradient(top, #eee, #ccc);
background-image: -o-linear-gradient(top, #eee, #ccc);
background-image: linear-gradient(top, #eee, #ccc);
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#eeeeee', EndColorStr='#cccccc');
border: 1px solid #777;
padding: 0 1.5em;
margin: 0.5em;
font: bold 1em/2em Arial, Helvetica;
text-decoration: none;
color: #333;
text-shadow: 0 1px 0 rgba(255,255,255,.8);
-moz-border-radius: .2em;
-webkit-border-radius: .2em;
border-radius: .2em;
-moz-box-shadow: 0 0 1px 1px rgba(255,255,255,.8) inset, 0 1px 0 rgba(0,0,0,.3);
-webkit-box-shadow: 0 0 1px 1px rgba(255,255,255,.8) inset, 0 1px 0 rgba(0,0,0,.3);
box-shadow: 0 0 1px 1px rgba(255,255,255,.8) inset, 0 1px 0 rgba(0,0,0,.3);
}
.button:hover
{
background-color: #ddd;
background-image: -webkit-gradient(linear, left top, left bottom, from(#fafafa), to(#ddd));
background-image: -webkit-linear-gradient(top, #fafafa, #ddd);
background-image: -moz-linear-gradient(top, #fafafa, #ddd);
background-image: -ms-linear-gradient(top, #fafafa, #ddd);
background-image: -o-linear-gradient(top, #fafafa, #ddd);
background-image: linear-gradient(top, #fafafa, #ddd);
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#fafafa', EndColorStr='#dddddd');
}
.button:active
{
-moz-box-shadow: 0 0 4px 2px rgba(0,0,0,.3) inset;
-webkit-box-shadow: 0 0 4px 2px rgba(0,0,0,.3) inset;
box-shadow: 0 0 4px 2px rgba(0,0,0,.3) inset;
position: relative;
top: 1px;
}
.button:focus
{
outline: 0;
background: #fafafa;
}
.button:before
{
background: #ccc;
background: rgba(0,0,0,.1);
float: left;
width: 1em;
text-align: center;
font-size: 1.5em;
margin: 0 1em 0 -1em;
padding: 0 .2em;
-moz-box-shadow: 1px 0 0 rgba(0,0,0,.5), 2px 0 0 rgba(255,255,255,.5);
-webkit-box-shadow: 1px 0 0 rgba(0,0,0,.5), 2px 0 0 rgba(255,255,255,.5);
box-shadow: 1px 0 0 rgba(0,0,0,.5), 2px 0 0 rgba(255,255,255,.5);
-moz-border-radius: .15em 0 0 .15em;
-webkit-border-radius: .15em 0 0 .15em;
border-radius: .15em 0 0 .15em;
pointer-events: none;
}
/* Hexadecimal entities for the icons */
.add:before
{
content: "\271A";
}
.edit:before
{
content: "\270E";
}
.delete:before
{
content: "\2718";
}
.save:before
{
content: "\2714";
}
.email:before
{
content: "\2709";
}
.like:before
{
content: "\2764";
}
.next:before
{
content: "\279C";
}
.star:before
{
content: "\2605";
}
.spark:before
{
content: "\2737";
}
.play:before
{
content: "\25B6";
}
Why use entities rather than images?
- Faster loading, because we’re talking about text here.
- Scalable, depending on font size.
- Styles as color and background are easy to update via CSS.
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: bold 1em/2em Arial, Helvetica;
There you go, you’ve just increased/decreased the button’s size!
Rendering & browsers support
The icons are added using the :before pseudo-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 Chrome screenshot.
/* Buttons and inputs */
button.button, input.button
{
cursor: pointer;
overflow: visible; /* removes extra side spacing in IE */
}
/* removes extra inner spacing in Firefox */
button::-moz-focus-inner
{
border: 0;
padding: 0;
}
/* If line-height can't be modified, then fix Firefox spacing with padding */
input::-moz-focus-inner
{
padding: .4em;
}
/* The disabled styles */
.button[disabled], .button[disabled]:hover, .button.disabled, .button.disabled:hover
{
background: #eee;
color: #aaa;
border-color: #aaa;
cursor: default;
text-shadow: none;
position: static;
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
}
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? :)
Update II
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!



This is awesome! Thanks.
Very good post! I think it is very very useful!
Catalin your CSS buttons are awesome! Very clean and well done.
Great! Especially the idea to code the icons without pictures but with the entities. That makes it more simple to try other colors.
Best of the best. Thanks for sharing!
Great examples. I really like these! :D
You cannot use Tab to move between these buttons. I’m not sure these even can be pressed using the keyboard.
Tested in Safari 5.1 on Lion.
Otherwise they look fabulous
They are standard anchor tags with just some (albeit awesome) CSS, not sure how that would break tabbing / keyboard nav.
It’s odd. Buttons behave ok in other browsers, but not in my Safari :)
Dmitri, I have done my tests on my Windows7 Safari 5.0.5 and the buttons are accessible using the Tab key.
Though, I’ve just tested on Lion’s Safari and it seems the Tab key is not working properly, as you pointed above.
To make it work I’m pretty sure you just need to set the
tabindexattribute for the buttons group you want to be accessible via keyboard.Thanks for the heads up!
also tab doesn’t work in IE ( tested with 8 ) :( and the demo
no indication at all which button is currently highlighted
They look great, except some of the icons do not show on my computer here at work (Firefox 7 on Windows XP). Actually only Favorite and Play are all right, the rest show a garbled character. Probably some fonts are missing from the installation…
gxg, I’ve tested this demo on Firefox 7 using Windows Vista and everything seemed to be just Ok.
Also, the font I used it is a common one: Arial, so there should be no problem with this matter.
So, I’m afraid I’m not sure what is the problem you encounter.
I have the same problem.
It works with Google Chrome on Vista and Win 7 but NOT on Win XP. Only the play-icon works. The other characters are blank. Maybe it’s a new version of Arial in Vista and Win 7?
I will make some additional tests on Windows XP soon and I’ll reply back.
Thanks for your feedback!
Maybe I found something:
http://www.alanwood.net/unicode/fonts.html
“Version 2.82 (1186 characters) was supplied with Windows 2000 and Windows XP”.
Windows Vista – “2792 characters (3381 glyphs) in version 5.01″.
If I understood it right Arial on Windows XP is an early version with not all characters.
Indeed, this seems to be a serious drawback, not all the chars are available to use…
Yes but there is a workaround. Download the latest version of Arial and embed it with @font-face. That should work.
http://www.fontspring.com/blog/the-new-bulletproof-font-face-syntax
Awesome!
Thx man nice job!
Internet Explorer 10? What the…
It’s about Internet Explorer 10 Test Drive :)
Nice work! Just a quick questions, what did you use to discover the various entities that you’re using here? I’ve been looking around, and haven’t had much luck finding a decent reference for iconographic entities.
Jason, here‘s a comprehensive list with the symbols.
This is awesome! As usual, except for IE, they look great. Thanks for this.
Great set! Thanks for sharing.
Great!
Just shared on my tech blog: http://www.greepit.com :)
Sarfraz
very nice, and a decent fallback for older browsers,
very well done!
Thanks, that’s exactly the point: degrade nice for older browsers.
Absolutely great job you’ve done. Thanks.
These buttons are excellent!
Having an issue trying to use these styles on buttons rather than on links for form submission. The height of the buttons are not the same as on links in IE7 (taller) and Firefox 3.6 (shorter). Any thoughts on correcting this?
James, as soon I’ll have some time I’ll update the article and fix that. Thanks for the heads up!
Simple and beautiful. Thank you. I will definitely use them :)
CSS3 is really amazing!
Did a post about this just now..
http://richarrdg.tumblr.com/post/9910745690/css3-awesome-buttons
hi,red
great! I like your websites. l have learned css3 from your website. Thank you very much. I will transition Chinese put on my blog.
one’s great trick for make a stylish button
thanks for tut’s ☺
Here’s a screenshot of the buttons on an iPhone 2G iOS 3.1.3
http://imgur.com/V1meN
Hernán, thanks for adding the iOS 3.1.3 screenshot. I think they look pretty well there.
Wow very nice – i’m currently working on a large scale web app so this will be handy indeed. Thanks a lot!
Thanks for the buttons! :)
+1 for button/submit support. I know you’re busy but I think we can all agree that these buttons look awesome.
It would also be great to see you add alternative colours to the grey :-)
Anthony, I already have something in mind, will let you all know when updates will be made.
I hope it will be quite soon.
Thanks :-)
Love the concept!
There you go, I just updated the article!
Now, the demo contains also buttons and inputs. I hope you like it!
thanks nice buttons..
Hey guys, you may check the demo again.
I just added two new colored buttons!
Red,
Great work, I really like these button styles!
I’ve found some strange behavior with Firefox (6.0.2) for input buttons.
After clicking on this buttons the background is white. It only returns to gray if I click outside the button. This not happens with the other links examples, and also this not happens with Chrome.
Any idea to solve this?
Thanks and I would use them!
Sebastian, the button has a
:focusstyle and that’s why you’re encountering this behavior. On focus, the default outline is removed and a light gray background is added.When clicking on an
anchorfor example, the page reloads as thehrefis blank and of course you lose the focus for that button.Instead, when clicking on an
inputorbuttonthe focus remains (automatically, that light background).This behavior is not encountered on Chrome (and other browsers) because that’s the way they do it. :)
The
:focusstate is useful when using Tab key to navigate so if you want to edit it, chose another style carefully.Thanks! Changed the focus style and now is working as I like.
Great work! :-)
is this really css3 !?
css3 is a cutting edge technique
Firefox 7 on my version of Windows 7 does not show the extra font characters whereas Chrome and IE9 had no problems. It took some digging but I found that the Arial font on my version of Windows 7 does not have the extra glyphs but there is the MS version of Arial which does have all the glyphs. My fix was to prefix the font list with “arial unicode ms” and now it works.
Thanks for the amazing tips for CSS3.
And again beautiful work! Love the buttons and the way of coding. You just got yourself another twitter follower!
Thanks MDK, nice to hear you like it. ;)
Can i use this Code for my Website free ? This buttons are very cool !
(PS: im german also sorry if my text isn’t understand)
BDG, feel free to use this code as you wish. ;)
I love the buttons, so I copied them to github, giving you credit. I hope that’s OK. Being on github has the advantage of allowing people to branch it to create different colours and themes etc., and potentially add to it as time goes on.
Let me know if there’s a problem with it being there.
https://github.com/thugsb/CSS3-Buttons
thugsb,
I’m glad you love these buttons and there’s no problem at all with github add! ;)
Very nice job Red!
+10 for using entities
Thanks, I’m glad you like it.
Awesome man , I learned some tips from this site thank you.
By Billa
Hey, thanks for your comment. I’m glad you like my articles.
Any chance for a download of these icons?
Really awesome! :)
One question: how to get the entities after, on the right, of the buttons? It seems more logical in a way, maybe?
I love this website, it’s such a source of inspiration! :)
THANKS!
Thanks for your kind words Chuch.
Regarding your updates, here’s what you need to do:
.button:before { float: right; margin: 0 -1em 0 1em; box-shadow: -1px 0 0 rgba(0,0,0,.5), -2px 0 0 rgba(255,255,255,.5); border-radius: 0 .15em .15em 0; }Hope that helps, good luck!
Thank you so much, it’s perfect and easy, as usual! :)
Also.. here are some more characters to compliment the buttons.
http://www.alanwood.net/unicode/
hi red
nice looks button please confirm can i add this button in this website http://www.crea8ivedesign.com
regards
Hey, feel free to use it. Good luck!
hi red
you have very nice stuff on website can you place our web site banner on your website right side? is that possible?
regards
crea8ivedesign.com
Red,
Hi, this is looks great, but i just can’t find the list of vector icons with code number for me to use with css3, do you know where do i can find list of vector icons with code!
Also is this possible to replace with my own vector, if so how can i create that with my own vector code!
AM
atleast give a download link man…
Man, there’s nothing to download. Just copy & paste the demo page source. ;)
Hello Red,
Thx a lot for your great tips.
I have made good use of them. :)
http://spectrum.robertgabriel.eu
Robert
These are my favourite css buttons! Thank you. But… where can I find a list with all the html entities you used in the css as “images”?
Check one of my previous comments. ;)
Thank you. Sorry but I didn’t read all comments and replies ;-)
By far one of your best work, I love these buttons!
Here’s an useful link for the symbols: http://rog.ie/post/9291629610/charcodeat-0-tostring-16-outputs-279c
These look great! Any idea how to style the type=”file” input? Specifically I’d like to single out the “choose” button itself.