Recently I talked about CSS cross-browser gradients and last week I wrote again about CSS3 gradients. So what I’m going to do today? I will show you how to put the CSS gradient feature in practical use.
In this article you will see how you can create a set of gradient buttons just with CSS (no images).

Oh no! Not another CSS3 buttons!
That’s what you may say but, oh yes :) … This is another buttons set, powered by almighty CSS3 (and IE gradient filters).
Features
- Scalability – Scale the buttons using font-size.
- Adjustability – Change padding and font-size and there you go.
- Flexibility – Apply the styles to any HTML elements.
- Fallback styles – Graceful degradation for other browsers.
- Usability – Normal, hover and active states are available.
“How it’s made”
- RGBA color mode
- Box shadow
- Text shadow
- Rounded corners
- Gradient patterns thanks to @leaverou for its enlightening article about CSS3 gradients techniques
HTML structure
Let’s see how the HTML looks for the blue button for example:
<a href="#" class="button button-blue"> <span>Button</span> </a>

Multiple classes are used in order to have minimal HTML and CSS files.
The top border could have been achieved with an inset box-shadow but, this way the CSS3 buttons will degrade graceful, as you will see later in this article.
The CSS
.button
{
margin: 10px;
text-decoration: none;
font: bold 1.5em 'Trebuchet MS',Arial, Helvetica; /*Change the em value to scale the button*/
display: inline-block;
text-align: center;
color: #fff;
border: 1px solid #9c9c9c; /* Fallback style */
border: 1px solid rgba(0, 0, 0, 0.3);
text-shadow: 0 1px 0 rgba(0,0,0,0.4);
box-shadow: 0 0 .05em rgba(0,0,0,0.4);
-moz-box-shadow: 0 0 .05em rgba(0,0,0,0.4);
-webkit-box-shadow: 0 0 .05em rgba(0,0,0,0.4);
}
.button, .button span
{
-moz-border-radius: .3em;
border-radius: .3em;
}
.button span
{
border-top: 1px solid #fff; /* Fallback style */
border-top: 1px solid rgba(255, 255, 255, 0.5);
display: block;
padding: 0.5em 2.5em;
/* The background pattern */
background-image: -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.25, rgba(0, 0, 0, 0.05)), color-stop(.25, transparent), to(transparent)),
-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(0, 0, 0, 0.05)), color-stop(.25, transparent), to(transparent)),
-webkit-gradient(linear, 0 0, 100% 100%, color-stop(.75, transparent), color-stop(.75, rgba(0, 0, 0, 0.05))),
-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.75, transparent), color-stop(.75, rgba(0, 0, 0, 0.05)));
background-image: -moz-linear-gradient(45deg, rgba(0, 0, 0, 0.05) 25%, transparent 25%, transparent),
-moz-linear-gradient(-45deg, rgba(0, 0, 0, 0.05) 25%, transparent 25%, transparent),
-moz-linear-gradient(45deg, transparent 75%, rgba(0, 0, 0, 0.05) 75%),
-moz-linear-gradient(-45deg, transparent 75%, rgba(0, 0, 0, 0.05) 75%);
/* Pattern settings */
-moz-background-size: 3px 3px;
-webkit-background-size: 3px 3px;
background-size: 3px 3px;
}
.button:hover
{
box-shadow: 0 0 .1em rgba(0,0,0,0.4);
-moz-box-shadow: 0 0 .1em rgba(0,0,0,0.4);
-webkit-box-shadow: 0 0 .1em rgba(0,0,0,0.4);
}
.button:active
{
/* When pressed, move it down 1px */
position: relative;
top: 1px;
}
Blue button:
.button-blue
{
background: #4477a1;
background: -webkit-gradient(linear, left top, left bottom, from(#81a8cb), to(#4477a1) );
background: -moz-linear-gradient(-90deg, #81a8cb, #4477a1);
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#81a8cb', endColorstr='#4477a1');
}
.button-blue:hover
{
background: #81a8cb;
background: -webkit-gradient(linear, left top, left bottom, from(#4477a1), to(#81a8cb) );
background: -moz-linear-gradient(-90deg, #4477a1, #81a8cb);
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#4477a1', endColorstr='#81a8cb');
}
.button-blue:active
{
background: #4477a1;
}
And so on for the other buttons…
Browser support
Mozilla 3.6+
Full support, including CSS3 gradient patterns (though I noticed some performance issues when page is rendered).

Webkit (Safari, Chrome)
The buttons are rendered very nice on Webkit browsers.

Opera 11
Unfortunately, Opera lacks any support for CSS gradients, still the buttons render very nice as other CSS3 features are not missing here.

IE6, IE7, IE8
With filters, CSS gradients are possible also when talking about IE6 or IE7.

IE9
Besides the other IE browsers, IE9 supports rounded corners and box shadows, although the corners don’t look perfect as you can see below.

That’s all!
It would be recommended to use conditional comments when using filters. This way your CSS file will be cleaner and you will avoid performance issues.
Having said that, I hope you enjoyed this article and if you did don’t forget to follow me on Twitter or to leave a comment below!



This tutorial that I been looking for, thanks for sharing. :D
this is awesome! been looking for this!
@Rudy and @Quan thanks for reading it!
that 1px border top on ‘span’ is very great idea, i really like it, keep posting, and thanks a lot
One thing I would change in the CSS would be to put the default declaration AFTER the vendor-specific declarations. For example box-shadow should come after -moz-box-shadow and -webkit-box-shadow. That way when full browser support arrives, your code will render according to the spec rather than specific to the vendor because the default declaration comes after the vendor declarations.
Gabe, that’s a good one! Thanks for pointing that out!
Good point on that one. Geez. I need to edit a ton of my CSS files to ensure I follow this, going forward.
IE 6,7, or 8 Rounded corners can fixed check with CSS 3 as well, go try it
The inner span is not required. You can have multiple backgrounds and the top border could be produced by an inset box shadow (box-shadow: 0 1px 0 rgba(255,255, 255, .5) inset;)
Thanks for the mention!
Thanks for your comment Lea, much appreciated!
I also mentioned above that alternatively, the top border could be produced by an inset box-shadow.
When I wrote this article, I just wished to have that top border also for the browsers that doesn’t support the box-shadow property.
Made my afternoon to find this. The white edge and the fallbacks are fantastic. As well, I played with where you marked off “pattern” and set it to “1px 1px” to get rid of the grid look that wasn’t my cup of tea. Also, I changed the font to simply “sans” because I personally don’t like Trebuchet. What’s also interesting was that I could merely add another class and style just the font-size (in pixels), and the whole button changed right along with it. Well done, and I tweeted this.
Thanks Volomike, nice to hear you liked it!
Crossbrowser? Just use images :)
Martin, of course, you can always use images for a 100% cross-browser solution.
But, as you already know, this is just a demo that shows that similar effect can be achieved without an extra HTTP request.
Thanks for your comment!
Anyone having issues with these buttons on FF4? I’m noticing it’s much different than FF3, showing me harsher radial lines instead of a smooth, blended radial. Of course, I was running FF4 in a Windows VM on Ubuntu, however. Must test on a real Windows system….
It seems that FF4 does not use the
background-sizeproperty with the-moz-prefix anymore.As a solution: add also the
background-sizeproperty.I’ll also update the CSS for this, thanks for letting us know!
Thank you SO much for the tutorial and clean-code in this. I was looking for how to properly do “rounded corners” on buttons but they have always stumped me. Adding gradients really makes them pop! Great job and your demo is appreciated! (side note: it seems IE always falls behind the curve of making things look nice. The round corners are … almost there on IE9, still disappointing though.)
Where are the rules that will work on IE8 and IE7?
OH never mind I see the Filter rules…. :-) Thank you.
No problem, nice to hear you found it! ;)
Shoot I can’t get it to work…I think I’ve been staring at code too long today….
Anyway around the IE9 corner issue?
Thanks for sharing…great, but problem with IE6.
Can I make two styles – one. And if so, how is this possible? I tried and I made it! But does not display the color of links for browsing. What I do not do that? Sorry for some mistakes. Its google translate from russian language
Nice buttons. Thanks for this article.
How do you define a button width so multiple buttons under each other can be the same width. Sorry if I’m missing something I don’t see this option anywhere… Thank You.
Hey Miklos, in the example above, all the anchors are set to
inline-blockand they contain the same text (Button – for demo purposes). That’s why they have the same size.Though, you can just define your own custom
widthfor the buttons.Catalin
I’m impressed with the use of 1px border for fallback. Nice tut and quite clear explanation. Thanks
Thanks, nice to hear you liked this tutorial.
Demo is slow as the hell. FF 9.0.1