Code an Awesome Animated Download Button With CSS3

by on 30th January 2012 with 30 Comments

screenshot

Follow along as we create a simple and fun download button using some fancy CSS3. Our button will use lots of fun goodies including border-radius, box-shadow, linear-gradients, z-index and transitions to achieve a unique double sliding drawer effect on hover.

As we go, I’ll discuss why some techniques that you might think to use should be avoided. Transitions are tricky to work with and are quite prone to refuse to work with certain properties. Read on to find out more.

The Concept

Loosely based on this idea, I wanted to create a download button with a cool sliding drawer effect where originally hidden information pops out when the user begins a hover event. To put my own spin on it, I decided to double the effect and create a drawer on both the top and bottom of the button (click here for a sneak peek of the finished result).

Here’s how it will work: using a combination of HTML and CSS, we’ll create three separate pieces. These include the main button and two smaller info panels. The smaller panels will initially hide under the larger button, then when the user hovers, one will slide upward and the other downward.

screenshot

As you can see, this will be a pretty easy project that is perfect for beginners that are looking to up their CSS skills. Especially worth learning is how we’ll utilize absolute positioning and stacking via z-index.

What Won’t Work

As I planned out this project, I came up with a couple of ways to make my concept work. Given that I’ve been on a pseudo element kick lately, the way that I chose to structure the project initially was through the use of :before and :after.

With these pseudo elements, we can code only the download button in our HTML and then add in the wings using pure CSS. It seems like an optimal solution and indeed it worked great… until I tried to animate the transition. No matter what I tried, I simply couldn’t get the transition to work.

After a little research I discovered that that only Firefox supports CSS transitions on pseudo elements. This is a real bummer that really limits the fun we can have with :before and :after, but on the upside I learned a valuable lesson that will save me a lot of time and trouble in the future.

In tutorials like this one you don’t often get to hear about where the author failed, but I think it’s important to communicate these failures so you can learn from them as I have. Now the next time you want to animate a pseudo element you’ll remember that it won’t work in most browsers!

Failures aside, let’s jump into a method that will work.

The Button

To begin, we’ll create and style our button. Once we have this in place, it’ll be easier to form the other elements. All we need in the HTML department is a single div containing a link. We could simply use the link for the button but we’ll need to group multiple objects together so a div is necessary.

Button Shape & Size

The HTML above should simply provide you with a plain text link. We’re going to transform this into a button with a set background shape and size. To do this, we start with some dimensions, add some color and set the display value to block.

.button a {
  display: block;
  height: 50px;
  width: 200px;
  background: #00b7ea;
}

Here’s a look at what your button should look like after this step. It doesn’t look like much yet, but it’ll be a fancy looking button before you know it.

screenshot

Type Styles

The first ugly thing about the button above that we’ll need to fix is the type, it’s currently a mess. Fortunately, this is easy to address. All we need to do is set the color to white, declare a font, and center it.

.button a {
  display: block;
  height: 50px;
  width: 200px;
  background: #00b7ea;
  
  /*TYPE*/
  color: white;
  font: 17px/50px Helvetica, Verdana, sans-serif;
  text-decoration: none;
  text-align: center;
  text-transform: uppercase;
}

There are a couple of interesting things to note here. First, notice that I’m using the “font” shorthand rather than running through reach font property individually. This is a great way to save space and keep your type styles nice and succinct. The order here is as follows:

screenshot

Here’s another nifty trick: I set the line-height to 50px to center it vertically in the button. Also notice that I removed the text underline and transformed the type to be uppercase. Why didn’t I just type it out in all caps in HTML? Because this is really a style choice and could change with a future redesign.

Now our button is looking much better!

screenshot

CSS3 Magic

At this point our button is still looking a little plain. If you’re cool with the minimal look, you can skip ahead. Otherwise, let’s make it a little more interesting. The first thing we’ll do is round off the corners. Make sure you add all three browser prefixes:

-webkit-border-radius: 10px;
   -moz-border-radius: 10px;
        border-radius: 10px;

Next up, we’ll toss in a box-shadow. Once again, we’ll need three versions to cover the various browsers. The shorthand value order here is horizontal offset, vertical offset, blur and color.

-webkit-box-shadow: 2px 2px 8px rgba(0,0,0,0.2);
   -moz-box-shadow: 2px 2px 8px rgba(0,0,0,0.2);
        box-shadow: 2px 2px 8px rgba(0,0,0,0.2);

Finally, we’ll toss in a gradient. Unfortunately, this requires a whole mess of code. The way gradients work recently change so not only do we need multiple prefixes, we also need multiple syntaxes to make sure we support everything. I’m going to be honest, I rarely code this stuff by hand. Instead, I use the Ultimate Gradient Generator and paste in the generated code. Here’s the result:

background: -moz-linear-gradient(top, #00b7ea 0%, #009ec3 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#00b7ea), color-stop(100%,#009ec3)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #00b7ea 0%,#009ec3 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #00b7ea 0%,#009ec3 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #00b7ea 0%,#009ec3 100%); /* IE10+ */
background: linear-gradient(top, #00b7ea 0%,#009ec3 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00b7ea', endColorstr='#009ec3',GradientType=0 ); /* IE6-9 */

Now our button is completely styled and looking fine. Here’s the result:

screenshot

Adding The Drawers

Now that our primary button is done, it’s time to add the little drawers that will slide out from the top and bottom (perhaps “wings” is the appropriate term). To do this, we’ll start by adding a little bit to our HTML:

Download

click to begin

1.2MB .zip

As you can see, I basically tossed in two paragraphs, each with a unique class that makes them easy to target (you could use some pseudo selectors instead if you really want to get fancy).

Default Paragraph Styling

Now jump over to your CSS and we’ll style the paragraphs. To start, we want to focus on the styles that both paragraphs will share. Styling both at once where possible helps keep our code clean and less redundant. Here’s a big chunk of code to think over:

p {
  background: #222;
  display: block;
  height: 40px;
  width: 180px; 
  margin: -50px 0 0 10px;
  
  /*TYPE*/
  text-align: center;
  font: 12px/45px Helvetica, Verdana, sans-serif;
  color: #fff;
  
  /*POSITION*/
  position: absolute;
  z-index: -1;
  
  /*CSS3*/
  -webkit-border-radius: 5px;
     -moz-border-radius: 5px;
          border-radius: 5px;

  -webkit-box-shadow: 2px 2px 8px rgba(0,0,0,0.2);
     -moz-box-shadow: 2px 2px 8px rgba(0,0,0,0.2);
          box-shadow: 2px 2px 8px rgba(0,0,0,0.2);
}

Now, this is a lot to throw at you all at once so I’ll walk through it step by step. The first thing we do is give the paragraphs shape, color and type styles exactly like we did on the button. The main difference is that these are smaller and use some margins to push them into place.

Next are the positioning styles. These are very important so be sure you understand them clearly. In order to make the wings appear behind the button, we need to apply z-index, which affects the stacking order of the elements. Think of this as a “send to back” sort of command. To make this work, we need to apply absolute positioning.

Finally, we added the same border-radius and gradient styles that we did before. I’ve kept these separated from the previous styles to keep things simple and clear, but to make things DRYer, you would probably want to rewrite your shared CSS3 styles to something like this:

.button a, p {
  -webkit-border-radius: 10px;
     -moz-border-radius: 10px;
          border-radius: 10px;
  
  -webkit-box-shadow: 2px 2px 8px rgba(0,0,0,0.2);
     -moz-box-shadow: 2px 2px 8px rgba(0,0,0,0.2);
          box-shadow: 2px 2px 8px rgba(0,0,0,0.2);      
}

Basically, any time you find yourself repeating or pasting styles multiple times, you’re making your code unnecessarily complex and should attempt to simplify.

At the end of this step, you’ll strangely see no change in your preview from last time. This is because we’ve hidden these elements behind the button. They’re there, you just can’t see them yet!

Hover and Active Styles

What we want to do next is take the wings that we just created and move them outward when the user hovers over the button. To accomplish this, we simply need to adjust the margins on each paragraph. Here we target each of the classes that we created, then move the .top one up and the .bottom one down. The .top class also required a slight line-height adjustment to look right.

.button:hover .top {
  margin: -80px 0 0 10px;
  line-height: 35px;
}

.button:hover .bottom {
  margin: -10px 0 0 10px;
}

While we’re here, we might as well throw some active styles on as well. These will take effect during a mouse down event.

/*Adjust Gradient*/
.button a:active {
background: #00b7ea; /* Old browsers */
background: -moz-linear-gradient(top,  #00b7ea 36%, #009ec3 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(36%,#00b7ea), color-stop(100%,#009ec3)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top,  #00b7ea 36%,#009ec3 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top,  #00b7ea 36%,#009ec3 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top,  #00b7ea 36%,#009ec3 100%); /* IE10+ */
background: linear-gradient(top,  #00b7ea 36%,#009ec3 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00b7ea', endColorstr='#009ec3',GradientType=0 ); /* IE6-9 */

}

/*Pulls in Wings*/
.button:active .bottom {
  margin: -20px 0 0 10px;
}

.button:active .top {
  margin: -70px 0 0 10px;
}

As you can see, what I’ve done here is adjust the gradient so that the top color stretches a little farther, then I brought the wings back in a little bit so that there’s a contracting effect when you click.

Now our button is looking awesome. All three of our states are working. When you’re not hovering, it looks like a plain old button. When you are hovering, the wings or drawers pop out. When you click, the wings come in a little and the gradient changes ever so slightly.

screenshot

Final Step: Add The Transition

At this point, everything appears to be working just fine. The only problem is that the hover effect takes place instantly and of course we’d like it to be a little more gradual. To accomplish this, go back to your paragraph block and add in a basic 0.5 second transition using all of the required prefixes.

p {
  background: #222;
  display: block;
  height: 40px;
  width: 180px; 
  margin: -50px 0 0 10px;
  
  /*TYPE*/
  text-align: center;
  font: 12px/45px Helvetica, Verdana, sans-serif;
  color: #fff;
  
  /*POSITION*/
  position: absolute;
  z-index: -1;
  
  /*CSS3*/
  -webkit-border-radius: 5px;
     -moz-border-radius: 5px;
          border-radius: 5px;

  -webkit-box-shadow: 2px 2px 8px rgba(0,0,0,0.2);
     -moz-box-shadow: 2px 2px 8px rgba(0,0,0,0.2);
          box-shadow: 2px 2px 8px rgba(0,0,0,0.2);
  
  -webkit-transition: all 0.5s ease;
     -moz-transition: all 0.5s ease;
       -o-transition: all 0.5s ease;
      -ms-transition: all 0.5s ease;
          transition: all 0.5s ease;
}

With this addition, the button will transition very nicely between the three different states.

See It In Action

We’re all finished! You should now have an awesome animated CSS download button that is sure to impress. Check out the live demo below or check out the code on Tinkerbin.

Demo: Click Here to Launch

screenshot

Want an even better version of the button with six different versions to choose from? Check out the awesome free download at our new sister site Design Curate.

Conclusion

Thanks for reading and following along. If you made it all the way through, pat yourself on the back for a job well done.

I hope you learned a thing or two about z-index or cool CSS3 tricks. If not, at least you got an awesome button out of the deal! Leave a comment below and let us know if you enjoyed the tutorial.

Comments & Discussion

30 Comments

  • http://www.themousepotatowebsite.co.za Larry Botha

    Nice work, Joshua!

    I’ve fought with pseudo elements and transitions previously… the sad thing is that currently only Firefox supports transitions on pseudo elements, and I’m not even sure to the extent of the support, but I’d imagine support is similar to that of the more familiar HTML tags.

    Hopefully other vendors are aware of this and it’ll be put into action – the power of pseudo elements is greatly under-appreciated!

  • http://www.lucadegasperi.com Luca Degasperi

    On the demo there’s an ugly animation on the button while the page finishes to load.
    You should probably add a transition only to the properties that will be animated otherwise it looks kinda ugly.

    • Sase

      Good advice!

  • http://beben-koben.blogspot.com/ Beben Koben

    I added more for cooler in
    .button:active .top & .button:active .bottom
    opacity: 0.8;
    background: #0d0;
    color:#111;
    border: 1px solid #000;
    hihihi…
    ty master \m/

    • http://hackers-store.blogspot.in/ Nipun Somani

      plz help me sir im confused with these code , where to paste these codes??????

      i don’t know HTML plz help me Where to paste these codes in blogger HTML plzzzzz

      or email me tutorial

      nipunsomani26@gmail.com

  • http://blog.bluezenith.com Donna Galassi

    Great tutorial… and a very cool button!

  • http://www.anildesign.com Anil

    Awesome!! thanks for sharing this.

    • http://hackers-store.blogspot.in/ Nipun Somani

      plz help me sir im confused with these code , where to paste these codes?????? pz

      i don’t know HTML plz help me Where to paste these codes in blogger HTML plzzzzz

      or email me tutorial

      nipunsomani26@gmail.com

  • http://blogverize.blogspot.com Nimsrules

    Awesome tutorial Joshua. Slowly and gradually CSS3 is gonna minimize the use of javascript on a website. Keep up the good work.

  • http://kbdesign.bdl.pl/ krzyho

    Nice effect, thanks!

  • Andrew Milne

    For some reason my top drawer seems to close slightly quicker than my bottom drawer. Can’t see any difference in my code to yours, anyone know what I might have done wrong?

  • Andrew Milne

    Actually, I just noticed yours is doing the same thing. Is there a way to get both drawers to close at the same time?

  • http://www.northerndiv.com Russbrown

    Superb tutorial thanks very much and well done

  • wildpainter

    I find the article interesting but do not understand why the sample buttons on the page don’t demonstrate the button action. I even tried another browser before I finally found the link to where I could view it in action.

  • leo

    Beautiful!

  • http://discographydorock.blogspot.com/ paulo

    oi galera como eu fasso para colocar esse botão no meu site ?

  • http://willwarren.com Will Warren

    Awesome tutorial, its always nice to see simple ideas that are cross-browser compatible at the same time. Good work!

  • http://theprabin.com/ An Ultimate World of Technology and Gadgets

    awesome…. i used this and glad to apply

    http://theprabin.com/

    thnx

  • http://intrig.com Mark

    My superpowers lie in C++, but I’m powerless in CSS. Thanks for the awesome button! Brilliant! See it action at intrig.com. I decided not to animate just quite yet.

  • http://dhafian.com/ Dhafian

    Cool Button!! I like this… I will use this button to my site later.. :D

    Thank you..

  • bighope

    thanks.

  • http://bedriftweb.no BedriftWeb

    Thanks a lot, fantastic work!

  • Ivan

    awesome…but there is no effect at IE9.

  • http://www.iamchandan.in chandan

    fooo awesome tutorial man :)

  • carl

    just found your button here:

    http://lucene.apache.org/solr/

    :-)

  • http://hackers-store.blogspot.com Nipun Somani

    Who can give me step by step guide becoz i don’t know HTML and im confused where to add these code plz pelp me

  • http://premium-area.blogspot.com Jasmine

    wow! what a cute button!
    i have implemented your code in my blogger blog but it does not work exactly as your demo page shows, so please guide me what mistake i am making and how to solve it.
    my test blog post where i have implemented it
    http://premium-stuff-guru.blogspot.com/2012/10/malwarebytes-anti-malware-pro-16501400.html

    looking forwrd

  • http://premium-area.blogspot.com Jasmine

    wow! what a cute button!
    i have implemented your code in my blogger blog but it does not work exactly as your demo page shows, so please guide me what mistake i am making and how to solve it.
    my test blog post where i have implemented it

    looking forwrd

  • http://hackers-store.blogspot.in/ Nipun Somani

    plz help me sir im confused with these code , where to paste these codes??????

    i don’t know HTML plz help me Where to paste these codes in blogger HTML plzzzzz

    or email me tutorial plz

    nipunsomani26@gmail.com

  • Nabaa

    Owesome, Many Thanks for sharing it Buddy´

Subscribe

Membership
About the Author