Cross-browser CSS gradient buttons

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”

View demo

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…

View demo

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!

Related content

Written by Red

Catalin Rosu, a.k.a Red, is a professional web designer and developer who loves to be creative and enjoys CSS techniques. Stay tuned for latest updates, subscribe to RSS and follow him on Twitter.

30 Responses to “Cross-browser CSS gradient buttons”

  1. Rudy Azhar says:

    This tutorial that I been looking for, thanks for sharing. :D

  2. Quan says:

    this is awesome! been looking for this!

  3. Red says:

    @Rudy and @Quan thanks for reading it!

  4. andy says:

    that 1px border top on ‘span’ is very great idea, i really like it, keep posting, and thanks a lot

  5. Gabe says:

    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.

  6. Shaz3e says:

    IE 6,7, or 8 Rounded corners can fixed check with CSS 3 as well, go try it

  7. Lea Verou says:

    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!

    • Red says:

      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.

  8. Volomike says:

    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.

  9. Martin says:

    Crossbrowser? Just use images :)

    • Red says:

      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!

  10. Volomike says:

    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….

    • Red says:

      It seems that FF4 does not use the background-size property with the -moz- prefix anymore.

      As a solution: add also the background-size property.

      I’ll also update the CSS for this, thanks for letting us know!

  11. 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.)

  12. Marian says:

    Where are the rules that will work on IE8 and IE7?

  13. Marian says:

    OH never mind I see the Filter rules…. :-) Thank you.

  14. Curtis says:

    Anyway around the IE9 corner issue?

  15. Wiki Blogger says:

    Thanks for sharing…great, but problem with IE6.

  16. Andrew says:

    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

  17. kevin says:

    Nice buttons. Thanks for this article.

  18. Miklos says:

    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.

    • Red says:

      Hey Miklos, in the example above, all the anchors are set to inline-block and 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 width for the buttons.

      Catalin

  19. fowziey says:

    I’m impressed with the use of 1px border for fallback. Nice tut and quite clear explanation. Thanks

  20. xxx says:

    Demo is slow as the hell. FF 9.0.1

Leave a Reply