How to create Skype-like buttons using jQuery

 

If you use Skype I am sure that you noticed that animated button for adding more people to a chat. When you click on it the icon on the left “jumps” for a few times. I love that animation. And that’s why I’m going to show you how to create the same button using jQuery and some simple CSS.

View demo

If you are not sure what button am I talking about, image below might help you.

 

And this is how our button will look like:

Ok, the task here is quite simple – I want the icon to jump for a few times when I hover the button. (In Skype window this icon jumps when you click on it, but I think it would be much better to have it jump on hover)

The button itself consist of an image and text placed inside of a link.

<a class="button" href="#">
    <img src="button.png" alt="" />Send info</a>
    or <a href="#">cancel</a>

Let’s style the button. CSS code for this is simple and won’t go through all the classes here. The key is that the icon is absolutely positioned inside its relatively positioned container – the link. The position of the icon is set to simulate Skype button, and that is to cover the left side of the button. Please note that you will see the rounded corners on the button only in Firefox thanks to -moz-border-radius- properties.

.button {
    padding: 4px 10px 3px 25px;
    border: solid 1px #8AB134;
    position: relative;
    cursor: pointer;
    display: inline-block;
    background-image: url( 'bkg.png' );
    background-repeat: repeat-x;
    font-size: 11px;
    height: 16px;
    text-decoration: none;
    color: #40740D;
    -moz-border-radius-bottomleft: 5px;
    -moz-border-radius-bottomright: 5px;
    -moz-border-radius-topleft: 5px;
    -moz-border-radius-topright: 5px;
}
.button img {
    position: absolute;
    top: -4px;
    left: -12px;
    border: none;
}
.button:hover {
    color: #8AB134;

Now the animation. We have three jumps on original Skype button – one large and two small jump. In first jump, icon will go up for 6px, in second 3px and in the last jump 2px. After each jump, the icon will go back to its original position defined in CSS. I guess it is pretty much similar to the Skype button.

$(document).ready(function(){
    $(".button").hover(function(){
        $(".button img")
            // first jump 
            .animate({top:"-10px"}, 200).animate({top:"-4px"}, 200)
            // second jump
            .animate({top:"-7px"}, 100).animate({top:"-4px"}, 100)
            // the last jump
            .animate({top:"-6px"}, 100).animate({top:"-4px"}, 100);
    });
});

Code is tested in Firefox, Safari and IE7. If this doesn’t work in IE6, I simply don’t care.

The icon used in this tutorial is from Developpers Icons set. Now try the demo, download the source code and enjoy styling your new buttons!  

78 Responses

  1. Davide Espertini 11. March 2009 at 13:57

    Oh great sample Janko! Really cool button like Skype! :D

  2. David Walsh 11. March 2009 at 14:16

    Great work! I love this!

  3. Janko 11. March 2009 at 14:17

    Davide, David: Thanks!!!

  4. thismat 11. March 2009 at 14:46

    I’m curious why you would go this route instead of a pure CSS solution?

    To avoid the extra class/css markup? Be a little more dynamic when adding new buttons?
    I can see both of those as valid solutions, but is there a usability hit if someone has no javascript?

    Good post, thanks!

  5. thismat 11. March 2009 at 14:48

    Hmm, thinking about it…I don’t think there would be a performance hit, though I bet if this doesn’t work in IE, it can easily be fixed to, great solution!

  6. Marco 11. March 2009 at 14:50

    That was pretty cute and works pretty nice. Although it doesn’t add anything functional, it does look pretty cool for the user.

    For this one, your tagline isn’t fully covered: It indeed is "good locking" but "functional"? Nah ;).

    Anyway, keep up the good work!

  7. Janko 11. March 2009 at 15:19

    thismat: Sure, there won’t be any usability hits, it just won’t jump. It works in IE7, though. ;)

    Marco: Yep, this is just "good looking". Tagline is more like a summary of the entire content :D

  8. Westley Knight 11. March 2009 at 17:11

    Love it! Gonna have to find some site where I can utilise this effect!

    My only issue with it is that the drop-shadow jumps with the icon, and you can see where it ‘cuts off’.

    Obviously this is my personal issue, I just can’t get myself past things that don’t react in accordance to the laws of physics! ;o)

  9. Westley Knight 11. March 2009 at 17:12

    Oh, and I’m not from Romania and spelt my domain wrong!

  10. peter 11. March 2009 at 18:15

    Tested this in IE6 and the bounce works, however the icon background is not transparent. I see a gray square that bounces.

    Should the bounce be extended to bounce on focus too? for keyboard users?

  11. Someone 11. March 2009 at 19:57

    You may set outline:none to remove it in Firefox.

  12. Gustavo 11. March 2009 at 20:57

    Some people just… grrr
    Caring about tagline? lol

    Good Work Janco! Keep going…

  13. Brian Arnold 11. March 2009 at 21:15

    That’s a pretty neat trick. I’d change it slightly, though.

    Looking at your first jump, it’s called with .animate({top:"-10px"}, 200).animate({top:"-4px"}, 200) – but what happens if you decide you want to move your button’s top to -3 or -2? You suddenly have to adjust all six animation calls – unless you lean on the fact that jQuery does relative scaling too. =)

    If you change it to .animate({top:"-=6px"}, 200).animate({top:"+=6px"}, 200) it’ll now move up 6 pixels, then down six pixels, regardless of where you started. Straight from the jQuery API for animate:

    [quote]As of jQuery 1.2 you can now animate properties by em and % (where applicable). Additionally, in jQuery 1.2, you can now do relative animations – specifying a "+=" or "-=" in front of the property value moves the element positively or negatively, relative to its current position.[/quote]

    Your demo is leaning on jQuery 1.2.6, so relative adjustments will work wonderfully. They’re absolutely great, just as functional, and allow you to separate presentation from interaction just that much more. =)

  14. Janko 11. March 2009 at 21:57

    Westley: Of course, I broke the laws of physics! This is functioning according to quantum physics :D Just kidding, you are right!

    peter: yes, sure, why not!

    "someone": Of course, I forgot that!

    Gustavo: Thanks!!!

    Brian: Good points, yes that’s more flexible. Thanks!

  15. Mario Awad 11. March 2009 at 22:29

    I love it. Thanks :)

  16. Moschos 11. March 2009 at 23:02

    Excellent, I launched Coda now to test it!! Keep up the good work informing about jquery,php etc!!
    Thanx

  17. Ervin Ter 12. March 2009 at 02:49

    Very nice! Keep up the good work.

  18. CyberFox 12. March 2009 at 05:01

    Very Nice!

  19. Nokadota 12. March 2009 at 05:14

    This is cool, thanks for the tut.

  20. Ricardo 12. March 2009 at 09:17

    I wonder if there’s a way to animate a gif using something like you did here… Make the gif shine a metallic glare just once when you pass over it (and only repeats if you pass over it once more).

  21. Janko 12. March 2009 at 09:29

    Thanks guys!

    Ricardo: yes, you could do something like this. Check out this tutorial: http://snook.ca/archives/javascript/jquery-bg-image-animations/

  22. Rob 12. March 2009 at 10:36

    really neat tutorial. something very cool i will definitely be "borrowing" in the future

  23. L.M 12. March 2009 at 10:51

    Good Job, Guy.

  24. senp 12. March 2009 at 14:01

    has a small problem with opera :(
    can’t use inline-block, change to block or add a block wrapper and use it as a pos:relative

  25. Bill Lowden 12. March 2009 at 15:36

    Cool animation! Thanks for explaining it so well.

  26. nemoprincess 12. March 2009 at 16:48

    Good Job! Thank you very much…

  27. James Cready 12. March 2009 at 18:44

    -webkit-border-top-left-radius: 5px;
    -webkit-border-top-right-radius: 5px;
    -webkit-border-bottom-left-radius: 5px;
    -webkit-border-bottom-right-radius: 5px;

    Why you hatin’ on Mac?

  28. ZeroDotNet 12. March 2009 at 18:47

    Excellent article!!

    Added to my "nice features" collection.

  29. James Cready 12. March 2009 at 19:42

    A) You have 4 lines of CSS that could be summed up by: -moz-border-radius: 5px;
    B) You are ignoring Safari’s border-radius: -webkit-border-radius: 5px;

  30. Janko 12. March 2009 at 20:03

    Thanks everyone!

    senp: Thanks for the opera tips!

    James: You are right, it’s not perfect. I assume you don’t like it then.

  31. rubycat 12. March 2009 at 20:16

    I’m a dumba$$…it looks great but doesn’t actually work. Like, clicking on that sexy button doesn’t submit the form I’m using it on. Have I missed something obvious? I didn’t quite understand the reason for wrapping this all in a link and now am wondering if I misunderstood what this can be used for?

  32. T-Law 13. March 2009 at 01:42

    Thanks ;) I threw IE6 :)

  33. Kampanye Damai 13. March 2009 at 05:45

    Great, that’s all I need. I’m studying about jQuery, thanks.

  34. Stephon Marbury Shoes 13. March 2009 at 10:17

    Hi Janko. thanks for sharing this coding. I want to try this skype button in my blog.
    thanks again.

  35. Bilard 13. March 2009 at 12:01

    This is really great! Thanks!

  36. Patternhead 13. March 2009 at 16:06

    Nice trick. jQuery rocks

  37. terminator 14. March 2009 at 01:34

    whoow cool button , nice to look wiil be my blog widget
    thank you very much

  38. De'Star 18. March 2009 at 09:32

    Awesome! It will complete my blog. Keep it up!

  39. Caina 18. March 2009 at 19:41

    Greate!!

  40. xaccrocheur 24. March 2009 at 09:57

    Hi all, nice reading, most notably about the webkit selectors (what is this non-standard nonsense ? One rule by browser ? feh) and Janko, your button is very nice. Only it errors in firebug, may be a PB w/ a new version of the main lib :

    handler is undefined
    trigger()()jquery-1….6.min.js (line 25)
    ready()()jquery-1….6.min.js (line 26)
    nodeName()()jquery-1….6.min.js (line 21)
    filter()()jquery-1….6.min.js (line 12)
    ready()()jquery-1….6.min.js (line 26)
    ready()()jquery-1….6.min.js (line 26)
    (?)()()skype_buttons (line 10)
    onreadystatechange()()jquery-1….6.min.js (line 27)
    onreadystatechange()()jquery-1….6.min.js (line 27)
    nodeName()([function()], function(), undefined)jquery-1….6.min.js (line 21)
    onreadystatechange()()jquery-1….6.min.js (line 27)
    [Break on this error] while(elem=second[i++])first[pos++]=elem…r)delete events[type][handler.guid];else

    ## (this from your demo page)

    g is undefined
    (?)()()jquery.j…e3Q%3D%3D (line 1)
    (?)()()jquery.j…e3Q%3D%3D (line 1)
    (?)()()jquery.j…e3Q%3D%3D (line 1)
    (?)()()jquery.j…e3Q%3D%3D (line 1)
    (?)()()jquery.j…e3Q%3D%3D (line 1)
    (?)()()jquery.j…e3Q%3D%3D (line 1)
    (?)()()dedie.ma…iva.co.ma (line 30)
    (?)()()jquery.j…e3Q%3D%3D (line 1)
    (?)()()jquery.j…e3Q%3D%3D (line 1)
    (?)()([function(), function(), function()], function(), undefined)jquery.j…e3Q%3D%3D (line 1)
    (?)()()

    ## (this from my own page)

    Thanks a lot !

  41. Janko 24. March 2009 at 11:38

    xaccrocheur: you are right, but I really don’t know what is the problem :(

  42. riant 26. March 2009 at 03:10

    So cool,Thanks for your share.

    By the way, I am a Chinese.

  43. heh 6. April 2009 at 02:47

    dont u fink it iz indeed ratha stupid to say "i dont care" like a 4 year old?

  44. Janko 6. April 2009 at 08:36

    @heh: Nope, I don’t think it’s stupid. Read the article.

  45. Stas 6. April 2009 at 17:51

    Thnx, Great solution!

    ps: the code after "The button itself consist of an image and text placed inside of a link." has one unnecessary tag A (in the last line)

  46. Hardy 8. April 2009 at 20:08

    That’s definitely a great idea I’m going to use in some of my next projects! TY fot that inspiration!

  47. sachin 10. April 2009 at 08:20

    Good tutorial and really useful..thanks

  48. riant 10. April 2009 at 11:13

    And I want to know, If I want to set buttons more then one in a page, what should I do? thank you.

  49. Pintocas 10. April 2009 at 12:18

    That’s cool

  50. lucapette 14. April 2009 at 09:12

    Simple and elegant solution, thank you for the job done. I think i could use it in the future.

  51. Photoshop 14. April 2009 at 09:30

    Really cool trick

  52. gentax 14. April 2009 at 11:44

    thanks so much, nice effect ;)

  53. Alex 14. April 2009 at 12:44

    Why are you using nested links? Those JS errors are most likely caused by this blatant disregard to simple HTML rules :)

  54. Alex 14. April 2009 at 13:06

    Never mind my last post – the demo itself is properly structured, but the HTML for the button on this page has an extra tag.

  55. CoryMathews 15. April 2009 at 01:13

    This does not work in Opera 9.64

  56. Janko 15. April 2009 at 08:40

    Thanks everyone!

    Stas: Thanks for letting me know, I haven’t noticed that – removed!

    riant: You just repeat the button as many times as you want on the page :)

    Alex: no problem, my mistake!

    CoryMathews: I have a bad habit not to test my demos in Opera :D Looks like the icon gets broken during animation.

  57. Guta 15. April 2009 at 18:20

    Bravo Janko,

    Excellent "How-to" !!!

    Svaka cast!

  58. Eric A. Maginniss 17. April 2009 at 21:59

    That’s a beautiful animation. The only problem that I can see with it (which happens with a lot of content using animations) is that it continues to stack animation events even as one is playing. If you run your cursor across the button 20 times quickly and then move it away, you will continue to see bouncing for several seconds. The best way to prevent this is to not append new animation actions while one is still playing.

    Thanks,
    Eric

  59. Janko 18. April 2009 at 10:21

    Guto: Hvala!!!

    Eric: Absolutely true, I missed that. Thanks!

  60. Toni 18. April 2009 at 12:51

    Hvala, hvala :)

  61. Matthias 18. April 2009 at 14:52

    Simply nice! I like it. :)

  62. Stefan 20. April 2009 at 21:07

    thx, i changed your js code to

    [quote]
    $(document).ready(function(){
    $(".button").hover(function(){
    $(this).children( "img" )
    .animate({top:"-10px"}, 200).animate({top:"-4px"}, 200) // first jump
    .animate({top:"-7px"}, 100).animate({top:"-4px"}, 100) // second jump
    .animate({top:"-6px"}, 100).animate({top:"-4px"}, 100); // the last jump
    });
    });
    [/quote]
    then it works with several buttons on same page

  63. ahmedstudio 21. April 2009 at 16:14

    pls i wanna make this effect in button control in Visual studio 2005
    this code for button control

    <asp:Button ID="Button1" runat="server" CssClass="button" Text="Button" />

    who can i add icon pls any one tell me

  64. Janko 22. April 2009 at 13:07

    Toni, Matthias: thanks!

    Stefan: Thanks for the snippet :)

    ahmedstudio: it should work with asp:button as well because it uses "button" class.

  65. CssRain 28. April 2009 at 15:40

    good work。

    I do it like this.

    Link:http://www.cssrain.cn/demo/skypebuttons/SkypeButton2.html

    哈哈

  66. Anderson Aguiar 29. April 2009 at 14:21

    Very Nice! Jquery r0x

  67. zhang 30. April 2009 at 07:38

    Cool,I like it.

  68. Steffi 2. May 2009 at 21:13

    This Butons looks very nice. I will make now someone, test and then customize them a little bit. Thx for this great helpfully post.

  69. Avelino 8. May 2009 at 17:54

    Hi.

    I found a javascript error :

    Error : ‘guid’ is null or not an object.

    Anybody has found the solution?

    Thanks a lot.

  70. awake 11. May 2009 at 01:26

    FYI… Does not work as it should on Opera

  71. Keith D 18. May 2009 at 19:54

    I wasn’t sure what you were on about… Just looked at your demo and saw the animation.. great stuff, made me smile.

    These tuts are fantastic, clear and well set out plus the source code is always helpful.

    More jQuery please.

    Thanks.

    Keith D

  72. Pablo 21. July 2009 at 22:11

    Love the effect. Subtle but adds a little wow! to the buttons. I’d like to see it animated through a parabolic bounce to make it more realistic but it’s a nice bit of inspirational design.

  73. philip beel 17. September 2009 at 11:25

    Hi, really great idea!

    One suggestion tho. I noticed that if you repeatedly hover over the button the animate function stacks up. Not a big issue, but you could fix it pretty quickly by doing this:

    $(":not(:animated)", this).animate(…)

    Hope this helps,

  74. Andreas 7. October 2009 at 11:59

    hello janko,
    great, that’s all I need. I’m studying about jQuery, Thanks.

  75. Bryan 21. October 2009 at 21:02

    One thing I noticed was CssRain’s link works in Opera but it doesn’t reset itself to the original position.

    Other than that opera issue the original script is great.

  76. Speller 24. October 2009 at 22:42

    i really like it and I’m gonna use it with philip bell small fix. Thanks

  77. matt 14. December 2009 at 04:57

    as Eric had mentioned, the animation continuing is a little annoying, and fortunately, all you need is to add a stop() before you animate. nice tut though

  78. dec 25. January 2010 at 09:54

    @senp "has a small problem with opera Frown
    can’t use inline-block, change to block or add a block wrapper and use it as a pos:relative"

    use ""display:block;float:left;" to sort the problem