I am available for freelance work - HIRE ME

Create a Colourful Web Button with CSS

posted by Matt Ward on Mar 17, 2010.

In this tutorial, we will take a look at a technique for creating your own multi-state web buttons using HTML, CSS and image sprites. We’ll look at both the Photoshop work as well as the code. You’ll also be able to download all the files.

Sometimes, I think that there are not nearly enough tutorials here on the Echo Enduring Blog. There are articles and freebies, but not many technical expositions (and the like). I suppose that part of the reason is that I have a tendency to write these crazy long tutorials, which take an equally crazy amount of time to compose. Those usually get posted on other sites, though, like SpyreStudios, and most recently, TutToaster.

Today, though, I hope to start changing that trend, with a relatively quick tutorial about how transform a simple HTML link into a button-like UI element using a single image sprite and some simple styles, including some pseudo CSS3 properties.

Step 1

First, we want to start by opening up Photoshop itself, and creating a new document. We’re going to want our button to be exactly 30 pixels in height, so let’s set the file size to 100px by 30px.

Create a new document

Create a new document

Next, we are going to want to fill the canvas with a simple colour. For this example, I’ve just chosen a basic green. It’s not to light and not to dark, and will work well as a temporary background.

Set the background to a flat colour

Set the background to a flat colour

Next, set the foreground colour to black and select the gradient tool. At the top left hand corner of the application window, there should be a simple gradient drop down, which will allow you to select the type of gradient that you want to use. Select the Foreground to Transparent option (usually the second), which will create a gradient that fades from black to transparent.

Create a new layer and use the gradient tool to fill that layer with a gradient that is black at the bottom and transparent at the top, allowing the green to show through, like this.

Create a black-to-transparent gradient

Create a black-to-transparent gradient

Finally, reduce the transparency of this new gradient layer all the way down to 30%, so that it creates a simple shading effect over the green.

Reduce the opacity of the gradient

Reduce the opacity of the gradient

Step 2

Now, select the two layers together, right click and choose Convert to Smart Object from the contextual menu. This will merge the two layers into an object that can be opened like a separate Photoshop document and modified at will.

Create a new Smart Object from the layers

Create a new Smart Object from the layers

Next, select Image » Canvas Size from the menu. In the dialog box, set the height to 90 pixels, which is exactly three times the current height. Then press OK. The canvas should now look something like this:

Increase the canvas size

Increase the canvas size

Right click on our Smart Object layer and select New Smart Object via Copy from the contextual menu. Drag the new layer up so that it sits directly above the existing Smart Object, like this:

Duplicate the Smart Object and align it to the top

Duplicate the Smart Object and align it to the top

Repeat this process once more, dragging the duplicate to the bottom. You should now have three identical green bars, all stacked on top of one another. This will form the basis of our CSS sprite.

Duplicate the Smart Object again and align it to the bottom

Duplicate the Smart Object again and align it to the bottom

Step 3

For the sake of organization, let’s rename our Smart Objects. Call the top object “button”, the second “hover” and the third “active”. Next, double click the preview or icon of the active object to open it up in a new layer. What you will see should be exactly what we had prior to creating our initial Smart Object.

We’re just going to make one slight adjustment here, by increasing the opacity up to 70%, and darkening the shading on the button.

Increase the opacity again

Increase the opacity again

Save the document and it will update in our main Photoshop file.

Our updated document should look like this

Our updated document should look like this

Step 4

Now, open the hover Smart Object. Go ahead and delete the gradient layer (which we won’t need) and then create a new empty layer. Or, of you perfer, just delete the contents of the gradient layer. Either way, you should end up with a completely blank layer over the green background.

Set the foreground colour to white and select the Gradient Tool again. Make sure that the Foreground to Transparent option is selected. We also need to set the gradient mode to radial rather than linear. Then, in the top center of the blank layer, create a gradient.

Create a white-to-transparent gradient

Select the gradient layer and adjust its sizing so that it reaches to the very edge of the canvas.

Reduce the opacity

Reduce the opacity

Save the Smart Object. The entire document should now look something like this:

This screenshot shows the three different states

This screenshot shows the three different states

Step 5

This step is super simple, but critical. Open each of the Smart Objects separately and either hide or delete the green background. Once you’ve done that, the final image should look something like this:

Remove the green backgrounds and save as a PNG

Remove the green backgrounds and save as a PNG

It’s a bit difficult to see, but the transparency is an important factor. Next, select File » Save for Web & Devices from the menu and save the file as a PNG-24 and name it buttons-sprite.png in a folder called images.

Step 6

Alright, now it’s time to switch gears and look at some code. Start by creating a basic HTML file structure. With an application like Coda, this is really easy by using just a few code snippets. I’m not going to include any of that code here, but if you’re really interested, you can have a look at it in the HTML of the demo.

What I do want to have a look at, though is the following few lines of HTML, which you should include in between the <body> and </body> tags.

<div class="buttonWrap">
<a class="button b1" href="#"><span>Submit</span></a>
<a class="button b2" href="#"><span>Reset</span></a>
<a class="button b3" href="#"><span>Validate</span></a>
<a class="button b4" href="#"><span>Cancel</span></a>

That’s really all we need. Each link is given the class of button, which we will use as a hook to apply out basic button styles. They are also given second, unique classes, which we will use to give each button it’s own unique colour!

The <div> wrapper will also be important, but we’ll touch on that as we go through the various styles.

Step 7

First, start by adding a basic body style, which we will use to change the main font family displayed on the page.

font-family: helvetica, arial, sans-serif;}

Now, we want to add the style for the button itself.

display: block;
height: 28px;
background: #777 url(images/button-sprite.png);
border: 1px solid #777;
text-decoration: none;
font-size: 14px;
padding: 1px;
margin: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-moz-box-shadow: 0px 0px 2px #888;
-webkit-box-shadow: 0px 0px 2px #888;

We basically set the display mode of the link from inline to block, set the height to match the 30px height that we had already established for our button and set some of the other dimensional properties. The border-radius property is used to create a rounded corner effect, and the box-shadow basically adds a soft drop shadow behind the button.

Next, we want to work on the inner <span> styles.

a.button span{
display: block;
color: #fff;
border: 1px solid #888;
padding: 6px 5px 4px 5px;
border-spacing: 0px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;

Again, we want to set the display mode from inline to block. Then we basically set up a border to help create a pseudo-beveled effect in our finished button. The padding is also a compromise between the Mozilla and WebKit renders, which seem to handle the padding issue differently. There has to be a better way, but I haven’t figured it out (if you know, please leave a comment). Looks good in Firefox, and not-too-bad in Safari.

Lastly, we add just a few extra styles to handle the :hover and :active states.

a.button:hover span{
background: url(images/button-sprite.png);
background-position: center;
background-position: 0px -60px;
a.button:active span{
background-image: none;

When we hover, we set the background of the <span> to the hover portion of our CSS sprite, giving a soft illumination effect. When the button is clicked, we strip out the hover state and set the main background to the active portion of the sprite, creating a “pushed” effect.

Step 8

Finally, we’re going to add styles for the individual classes, each of which will have a different colour combination.

a.b1{background-color: #012e40; border-color: #012e40;}
a.b1 span{border-color: #0a475f;}
a.b2{background-color: #025959; border-color: #025959;}
a.b2 span{border-color: #0f7a7a;}
a.b3{background-color: #d93704; border-color: #d93704;}
a.b3 span{border-color: #f45826;}
a.b4{background-color: #8c0303; border-color: #8c0303;}
a.b4 span{border-color: #b31212;}

In each case, the background colour and border colour of the link itself are set to be the exact same. Then, the border colour of the <span> is set to a slightly lighter shade of the same colour. There’s no real science to how I determined that lighter colour. I just basically eyeballed it in Photoshop. Feel free to take a more exact approach.

Also, this is probably the best place to note that, in the class definitions for the links, the unique classes must come after the “button” class. This way the properties of the unique classes overwrite those of main button class. If the classes are reversed, this won’t happen, and all the unique styling will be lost.

Step 9

Last but not least, add the following styles for the main <div> wrapper.

.buttonWrap a{float: left;}

This will allow all the block level buttons to float in a row, rather than having each button stretch to the width of the entire page. However, because we are using a float, we will also want to use the .clearfix method and add these styles:

.clearfix:after {
clear: both;
content: ' ';
display: block;
font-size: 0;
line-height: 0;
visibility: hidden;
width: 0;
height: 0;

.clearfix {
display: inline-block;}

* html .clearfix {
height: 1%;}

.clearfix {
display: block;}

All this will do is help ensure that the <div> wrapper will retain its proper shape, since floating without this will actually cause it to collapse. To learn more about the Clearfix method, check out the articles How To Clear Floats Without Structural Markup and Lessons Learned Concerning the Clearfix CSS Hack.

Beyond that, you can go ahead and style the rest of the page however you want.

The Final Effect

After all those steps and work, you can sit back and enjoy your buttons! Here is a screenshot of what they should look like:

Here are our for CSS buttons

Here are our for CSS buttons

One final word of caution: the selectors for these buttons are really general, so be warned that writing rules with more highly specific selectors could potentially cause the design to break. Be careful and always pay attention to specificity.

Demo & Download

If you want to see this technique in action, please feel free to check out the live demo, which has been tested in both FireFox 3.5.8 and Safari 4.04, both on the Mac. Sorry IE users.

Also, feel free to download the Echo CSS Button (1004) files in the form of a single zip archive.


There you have it. I hope you find this tutorial interesting. As I already mentioned, there is a slight quirk in terms of some of the padding between Mozilla and WebKit. I’m really not sure what the issue is here, but if I figure it out, I will come back and update this post.

Of course, if you know the answer to that little issue, please feel free to post it in the comments below. Or, if you have any other insightful thoughts or comments about what I’ve written, please feel free to share it.

Post A Comment

Also from Echo Enduring Media:

An Unfolding Tale

About the Author

Matt Ward is a digital artist who lances freely under the moniker of Echo Enduring Media, and specializes in graphics design, illustration and writing. He is also the Creative Director for Highland Marketing, a creative direct marketing company based out of Waterloo, Ontario. You can follow Matt on Twitter

Like this post? Help Promote it!


Mar 18, 2010

Ren says:

Thnx – nice tutorial – works fine on IE7 & IE8 btw !

Mar 18, 2010

Leonardo Chaves says:

very nice and useful. Thanks for share it

Mar 18, 2010

Silverfish Extermination says:

This blog has so much Great information in it that i could spend all week reading it.

Mar 20, 2010

Li Ma says:

Great Write up on this CSS tutorial, very useful for all the interactive web designers out there. Thanks for sharing!

Mar 23, 2010

DyDesign says:

This is very neat and detailed. Expect more from you! :D

Apr 7, 2010

website erstellen says:

These really helped me to build my homepage, I can really appreciated if people take some time and write a usefull tutorial.

May 28, 2010

Sivaranjan says:

This is incredibly useful , but a little tweaking here and there could give a much nicer effect. I am taking the liberty of adding this article to my css aggregator site at CSSFind.com. Hope thats ok with you.

Jun 1, 2010

Matt Ward says:

Thanks. Yes that’s no problem including the tutorial on CSSFind

Jul 8, 2010

e-profitbooster.com says:

This is the greate post and benificial to the user who work on website fields

dayanand from e-profitbooster.com

Aug 8, 2010

Silverfish Bug says:

I just love CSS.
Thanks for the post.

Sep 11, 2010

ExampleMag says:

Nice tutorial!
I’m personally where you have Step 4 use Filter–>Render–>Lightning effects to get a more interesting highlight instead of just a gradient tool.

Nov 2, 2010

Brett Widmann says:

Great tutorial. Thanks for sharing.

Nov 22, 2010

astral projection guide says:

Nice guide.

Aug 20, 2011

Web Design News says:

Thank you for sharing. Continue the great work! Will subscribe to your RSS.

Leave a Comment

Copyright © Echo Enduring Media 2009-2014