Skip to the content...

Welcome to the David Walsh Blog. I'm a MooTools, Dojo, jQuery, CSS, and PHP Web Developer located in Madison, Wisconsin, United States. Please contact me if I can make your experience on my website better.

MooTools Link Nudging

41 Responses »

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' });
	el.addEvents({
		'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?

Discussion

  1. November 6, 2008 @ 9:47 am

    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. November 6, 2008 @ 10:20 am

    yap, cool effect. i tried something like this on my page (main navigation “jumps” up) too months ago. http://www.bugeyes.de

  3. November 6, 2008 @ 11:49 am

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

  4. November 6, 2008 @ 12:06 pm

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

  5. November 6, 2008 @ 1:10 pm

    Works great, i did it ^^.

  6. patrick
    November 7, 2008 @ 4:05 am

    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. November 7, 2008 @ 8:53 am

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

  8. November 7, 2008 @ 8:57 am

    @Paul Davis: Can you provide a URL?

  9. dave newton
    November 7, 2008 @ 9:07 am

    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. November 7, 2008 @ 9:31 am

    @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. November 7, 2008 @ 9:40 am

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

  12. November 7, 2008 @ 9:56 am

    @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. November 7, 2008 @ 10:00 am

    @davis: Yay! It works! Thank you sir. =]

  14. dave newton
    November 7, 2008 @ 11:07 am

    @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. November 7, 2008 @ 11:35 am

    Great tutorial. Thanks for share !

  16. November 10, 2008 @ 9:57 am

    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. December 8, 2008 @ 2:22 am

    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
    January 28, 2009 @ 1:28 am

    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…
    el.addEvents({
    ‘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
    January 28, 2009 @ 1:39 am

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

  20. January 28, 2009 @ 8:46 am

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

  21. brane
    January 28, 2009 @ 12:43 pm

    @Caligula, @david:

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

  22. gijs
    February 6, 2009 @ 2:49 pm

    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
    February 6, 2009 @ 4:05 pm

    @gijs:

    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 });
    el.addEvents({
    ‘mouseenter’: function() { fx_in.start({ ‘padding-left’: 20 }); },
    ‘mouseleave’: function() { fx_out.start({ ‘padding-left’: 0 }); }
    });

    });

  24. gijs
    February 6, 2009 @ 7:50 pm

    @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

    Greets,

    Gijs

  25. February 7, 2009 @ 2:18 pm

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

  26. February 7, 2009 @ 2:35 pm

    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.

    Erik

  27. gijs
    February 7, 2009 @ 2:55 pm

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

  28. February 7, 2009 @ 3:03 pm

    Thank you so much. Here is the head of my page:

    window.addEvent(‘domready’,function() {
    //smooooooth scrolling enabled
    new SmoothScroll({ duration:700 }, window);
    });

    window.addEvent(‘domready’,function() {
    $$(‘#footer3 a’).each(function(el) {
    var fx = new Fx.Morph(el,{ duration:300, link:’cancel’ });
    el.addEvents({
    ‘mouseenter’: function() { fx.start({ ‘padding-left’: 20 }); },
    ‘mouseleave’: function() { fx.start({ ‘padding-left’: 0 }); }
    });
    });

    The link to my CSS:

    http://www.honestskin.com/src/css/global/global.css

  29. February 7, 2009 @ 3:52 pm

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

  30. dave newton
    February 8, 2009 @ 10:29 am

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

  31. February 8, 2009 @ 10:54 am

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

    Thanks.

  32. gijs
    February 8, 2009 @ 11:40 am

    perhaps you should your smooth scrool in the second window.addevent, do not use this twice

  33. gregg
    March 29, 2009 @ 5:45 am

    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!!!

Be Heard!

Share your thoughts with fellow developers of all skill levels! I want to hear from you!

Name*:
Email*:
Website:  
Wrap your code with <code> tags, f00!