MooTools Link Nudging

By  on  

Link nudging is the process of adjusting the padding on a link slightly to show a simple, tasteful "jump" when you place your mouse over a link. The effect is magnified when mousing on and off a link quickly. Here's the short snippet of code:

The MooTools 1.2

$$('#footer-topics-1 a').each(function(el) {  
	var fx = new Fx.Morph(el,{ duration:300, link:'cancel' });
		'mouseenter': function() { fx.start({ 'padding-left': 20 }); },
		'mouseleave': function() { fx.start({ 'padding-left': 0 }); }

Check out the links in my footer to see the effect. Short and simple, right?

Chris Coyier also uses this effect, and it just so happens we both implemented it a day apart. Great minds think alike?

Recent Features

  • By
    Conquering Impostor Syndrome

    Two years ago I documented my struggles with Imposter Syndrome and the response was immense.  I received messages of support and commiseration from new web developers, veteran engineers, and even persons of all experience levels in other professions.  I've even caught myself reading the post...

  • By
    Create a CSS Flipping Animation

    CSS animations are a lot of fun; the beauty of them is that through many simple properties, you can create anything from an elegant fade in to a WTF-Pixar-would-be-proud effect. One CSS effect somewhere in between is the CSS flip effect, whereby there's...

Incredible Demos


  1. At first I was doing it with margin-left, which works but is problematic as the animation can slide the link out from under your mouse (creating a mouseOut), which then starts animating back the other way (creating a mouseOver), and you get the Jitter thing going on.

    Also, more evidence that MooTools animation is smoother than jQuery.

  2. yap, cool effect. i tried something like this on my page (main navigation “jumps” up) too months ago.

  3. I love it, thanks. Your blog never fails to produce, even with small stuff like this.

  4. Crazy, simple and slim. i check it out!bThamnk you ^^

  5. Works great, i did it ^^.

  6. Patrick

    I’m curious, how would one do this in jQuery? In a site I’m working on I have jQuery stuff and I don’t want to have to have two libraries

  7. Cant seem to get it working. Hmm. I wouldn’t think using Milkbox along side it would create a problem.

  8. @Paul Davis: Can you provide a URL?

  9. Dave Newton

    Cute. From a usability perspective I’d think having the text of a link remove itself from under your mouse would be considered sub-optimal and counter-intuitive.

    I’ll adopt the idea, with the addition of something that enforces the notion that there’s still something under the cursor.

  10. @Dave Newton: My links are “display:block” so it’s not like clicking the link text’s original spot would cause a problem.

    @Paul Davis: Your problem is caused by giving all of the list items the same ID, which you cannot do. Change ‘id=”navlink”‘ to ‘class=”navlink”‘ and you MooTools selector to “$$(‘.navlink’)”

  11. @david: Ok, I’ve done that. Still no luck, do I need to apply some CSS .navlink string?

  12. @Paul Davis: You went a little stray, but that’s ok. Change your Moo selector to:

    $$('.navlink li a')

    Also, you need to add “domready” code:

    window.addEvent('domready',function() {
    //your current Moo code goes here....
  13. @davis: Yay! It works! Thank you sir. =]

  14. Dave Newton

    @David: I know, but it’s still disconcerting and non-obvious. Not horribly so, but enough so that I wouldn’t feel comfortable deploying it as-is.

  15. Great tutorial. Thanks for share !

  16. Nice effect, I just implemented it on my site! (jQuery’fied) :)

    To avoid the text within the links wrapping I’ve applied a preliminary left and right padding (via CSS) and then I animate both of them (reducing the right padding and increasing the left padding at the same time) – this makes sure that there is the same amount of space for the text as there was before the animation, thus avoiding any confusing wrapping of text.

    I’ve only done a 5px movement, I think I could get away with 10px before it starts looking weird.

  17. What about…?

    $$(’#footer-topics-1 a’).each(function(el) {
        el.set(’morph’, {duration:300, link:’cancel’}).addEvents({
            ‘mouseenter’: function() { this.morph({ ‘padding-left’: 20 }); },
           ‘mouseleave’: function() { this.morph({ ‘padding-left’: 0 }); }
  18. Brane

    I’m not a JS expert, so this is something between a suggestion and a question…

    In the original code:

    $$('#footer-topics-1 a').each(function(el) {     
    var fx = new Fx.Morph(el,{ duration:300, link:'cancel' });   //This is the part that i'm talking about...
        'mouseenter': function() { fx.start({ 'padding-left': 20 }); },   
        'mouseleave': function() { fx.start({ 'padding-left': 0 }); }   

    new FX class command is inside the each function, so i think (this is the part that i’m not so sure) the code creates a new “FX Class” instance with the same name -“fx”- for every element that the selector returns. So, maybe carrying the FX instance out of the each loop and than calling it inside the loop can increase the performance. (?)

  19. Caligula

    @Brane: That would give each link the same Fx. Wouldn’t that cause some issues?

  20. @Brane: That wont work. You’d be “overwriting,” so to speak, each FX and it would only work on the last item.

  21. Brane

    @Caligula, @david:

    Yeah, you’re right. I completely misinterpreted the FX.Morph class concept. (I blame being sleepy :))

  22. gijs

    Is there a possibility that it will linear slide out and bounce:out back? can get it working together. For the rest: GOOD WORK!!!

  23. Brane


    If I don’t misunderstand what you ask, it can be done like this:

    $$('#footer-topics-1 a').each(function(el) {     
        var fx_in = new Fx.Morph(el,{ duration:300, link:'cancel', transition: Fx.Transitions.Sine.easeOut });
        var fx_out = new Fx.Morph(el,{ duration:300, link:'cancel', transition: Fx.Transitions.Bounce.easeOut });
            'mouseenter': function() { fx_in.start({ 'padding-left': 20 }); },   
            'mouseleave': function() { fx_out.start({ 'padding-left': 0 }); }   
  24. gijs

    @bran: thanks for the fast replay, unfortunately its to late for me, but i give it a try tomorrow. Is that the “normal” way to set up different transitions
    for the same event?

    @all: think that it will help for many people that they know you can use in stead of:

    .start({ ‘padding-left’: 20 });

    this is also possible:
    .start({ ‘padding-left’: ’20’, ‘background-image’: ‘url(bla.jpg)’ });

    so you can set more styles.

    i discovered that ‘background’: ‘url(bla.jpg) no-repeat red’ doesnt work in IE7, you have to set all styles fully listed, no shortcuts.

    Sorry for my english, i’m dutch



  25. For the life of me I can’t this script to work!!!!

  26. I’m a novice with mootools, and I thought I was getting better.. For the life of me, i can’t figure out why the nudging isn’t working….
    link text

    Can you help me? Check out the bottom of my page.

    Many thanks.


  27. gijs

    drop your code here, and stop make it difficult to leave your site.

  28. Don’t give up on me!! Your all I got!! :-)

  29. Dave Newton

    What doesn’t work? The links in the #footer3 section are nudged, the ones that aren’t in a #footer3 section aren’t.

  30. I got the nudge to work with jquery…. no luck with mootools.


  31. gijs

    Perhaps you should your SmoothScroll in the second window.addevent, do not use this twice

  32. Gregg

    Hey David,

    Thanks for sharing all your awesome stuff, I have had no problems implementing everything you have shared so far even though I have 0 knowledge of javasript or mootools but this one isn’t as clear as your other examples at all. I cant get this to work. How do you make the a tags associate with this script and is there anything I have to put in the css?

    Thanks for any help

    The noob!!!

  33. After upgrading to MooTools 1.3,
    The link-nudge not always come back to original position

    It does not always trigger mouseleave event.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!