Fluid Anchors – Smooth Anchors Using MooTools

Written by David Walsh on Thursday, August 23, 2007


This article may feature code that is no longer best practice in MooTools.
Click here to learn what has changed to make your code framework-compatible.

While we as programmers get more used to using AJAX and advanced javascript frameworks, we can only assume that our users will. At one time, it was acceptable to have elements dynamically just “pop into” the screen but now we must strive to make the experience smoother for our users. That’s why MooTools has put a big focus on the “Fx” part of their framework.

Page anchors are great. Page anchors allow us to link within the same page and this is especially useful for long pages where we can use a “top” anchor to move to the top of the page, saving the user miles of scrolling. The only problem with this functionality is that it is extremely jumpy; the user could click the anchor and be placed to the anchor point before they know what hit them. Not smooth.

MooTools provides an easy, customizable plugin to fix the chaos of anchors.

The Files

MooTools SmoothScroll Minimum Requirements (~19kb)
XHTML Working Example

The Code

window.addEvent('domready',function() { new SmoothScroll({ duration: 1800 }); });

The Usage

The only adjustment to your anchors is that you will need to add an id attribute to the anchor that mimics the same value as the name element.

<a title="sugar" name="sugar" id="sugar"></a>
<h1>Sugar!</h1>

You’ll not that the option I’ve used about is the duration option, which essentially sets the duration of the scroll. SmoothScroll calculates the amount of space on the page between the anchor link and the anchor and speeds the scroll automatically so that all scrolls take the ‘duration’ time to complete.

Another unobtrusive usage of the MooTools javascript framework to improve the functionality of your pages.


Epic Discussion

Commenter Avatar April 01 / #
Joshua says:

Great use of mootools! Any idea how you could get this to work on page load?

i.e. example.com/index.php?page=this#anchor

David Walsh April 01 / #
david says:

Joshua: Great question! I don’t know of a way to achieve this. I’ll look into this a bit more. I’m not sure if there’s a way to negate the browser’s functionality to go down so we can implement our own.

Commenter Avatar April 01 / #
Joshua says:

I was playing around with this a bit last night. Im not sure if its possible to bypass the browsers initial recognition of the anchor, but it should be possible to load the anchor with js and php.

So instead of having a link like:
?page=this#anchor

using one like:
?page=this&anchor=that

then in the head of a page, creating some php and js
if ($_GET['anchor'] !=”"){
some JS to load anchor
}

Now what that js should be Im not sure yet. Back in the day there were some autoclick functions but those have been phased out.

David Walsh April 01 / #
david says:

@Josh: Got you now. I think the JS should be something like:


var myFx = new Fx.Scroll('myElement', {
duration: 2000, //2 seconds
wait: false
}).toElement('element_id');

The above javascript code is Moo 1.2.

David Walsh April 01 / #
david says:

Oops — try this instead:


var myFx = new Fx.Scroll(window).toElement('myElement');

Commenter Avatar April 01 / #
Joshua says:

Great job David! It seems to works perfectly.

Commenter Avatar May 31 / #
hayden says:

id lve to use this but including the .js file breaks my slider:

Accessible News Slider: A jQuery Plugin
http://www.reindel.com/accessible_news_slider/

Commenter Avatar June 06 / #
Thomas says:

Hello.

I’m a beginner with Javascript and Mootools and your site is perfect for a guy like me :-)

I’d like users to scroll down to the bottom of a page, and there, a hidden ‘div’ should now be visible.
How can I get a page to scroll and simultaneously toggle a div property ?

Thanks

David Walsh June 06 / #
david says:

@Thomas: I believe you can add an “onComplete” to the scroll.

Commenter Avatar June 06 / #
Thomas says:

Thanks for this quick answer, but I don’t know how to do that… Isn’t it possible to launch two scripts at at the same time ?

Commenter Avatar June 16 / #
Lee says:

I am working on an anchor at the moment in JS, but i only want it to work when the page becomes scrollable.

How do i do this?

In other words, when the text can all fit on one web page browser i want the anchor to not work, but when they page becomes longer by the user adding data to it via a shopping cart function i want the anchor to work for reference purposes.

David Walsh June 16 / #
david says:

Lee: That’s a tough task. I don’t have a any ideas right away. Anyone else?

Commenter Avatar June 20 / #
ADI says:

First off, thanks for sharing.

Seems to be working perfectly in both IE and Firefox.

Safari doesn’t seem to be friends with the script unfortunately.

If I click the ’sugar’ link there is a 1 or 2 second pause, then a direct jump to the sugar section.

In my own site there is another strange behaviour with Safari.

Any ‘next’ link will smoothscroll to the top of the page (opposite direction) and then jump directly to the anchor location (where it was supposed to scroll to in the first place).

Anyone else experiencing weird behaviour in Safari or know how to fix this?

Commenter Avatar July 02 / #
Dan says:

Seems very jumpy in Safari 3.1.2 for me. Delay in the scrolling then jumps to the anchor. Any fixes?

Commenter Avatar July 21 / #
htl says:

It doesn’t work on Opera

Commenter Avatar July 21 / #
tstorm says:

I’ve been killing myself to get one of these smoothscroll things to work and I still can’t.

Quite simply, I’ve got this code in my header:
script type=”text/javascript” src=”mootools-smoothscroll.js”></script

script type=”text/javascript”>window.addEvent(‘domready’,function() { new SmoothScroll({ duration: 1800 }); });</script

And I’ve got the mootools-smoothscroll.js in the same level as my index.php. Seems like that should do it.

I’m sure to give an id to links. What could I be doing wrong?

David Walsh July 21 / #
david says:

Are you using a doctype?

Commenter Avatar July 21 / #
tstorm says:

Yeah. This one: !DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd”

David Walsh July 21 / #
david says:

@tstorm: Can you provide an example URL?

Commenter Avatar July 22 / #
tstorm says:

Sure. This site is a mess cuz I’m using it for css experimentation, but here it is: http://wiscostorm.net/stories/

David Walsh July 22 / #
david says:

@tstorm: The “sidebar” element is outside the HTML element, which could be the problem.

Commenter Avatar August 01 / #
Miguel says:

This is an amazing site and thanks for the mootools help! I was about to quit on mootools but then I found your site and tutorials and they really help! Guys like you make the internet what it is today.

David Walsh August 01 / #
david says:

@Miguel: I really appreciate that comment. I’ll keep striving to make Moo life easier for everyone!

Commenter Avatar August 01 / #
tstorm says:

I fixed that sidebar thing. Thanks.

Unfortunately, I’m still having problems getting it to work. Kind of a mystery, eh?

I appreciate the help.

David Walsh August 01 / #
david says:

@tstorm: You definitely have the path to the smoothscroll.js file wrong. It’s giving a 404 error. That’s a huge problem! :)

Commenter Avatar August 01 / #
tstorm says:

Yikes. Alright, let me check that. I deleted and re-uploaded some stuff with a back-to-the-drawing-board mentality, but I must have goofed the path. Thanks.

Commenter Avatar August 01 / #
tstorm says:

Woohoo! That did it! Thanks, man.

Now my question is, if I want the page to load in the middle section — so for instance, if you were to have your sample page load on the “sugar” section of the page — should I use a simple onload goToAnchor js or something else?

My page is nearing what I’d like it to do, but if I click on any of my categories at the bottom of the page, things are all out of whack.

I don’t really expect you to answer this one, David, since it’s totally above and beyond the already-above-and-beyond help you’ve been doling out, but in case anyone’s interested in exploring another js dilemma — this one specifically about the interaction between js and a wordpress blog.

Thanks again!

David Walsh August 01 / #
david says:

@tstorm: Have you tried Lim Chee’s solution here?

http://davidwalsh.name/mootools-onload-smoothscroll

Commenter Avatar August 01 / #
tstorm says:

Nice! That’s making my categories work (albeit a little jumpy), but how can I make it so that the page isn’t always loading from the top down? On my particular site, I want the top of the page and/or the #about anchor (which is close to the top) to remain out of sight unless someone clicks on about.

But I’m thinking this might get too messy, what with wordpress’s permalinks, pages, and categories. Maybe I need to think about some other workarounds.

Commenter Avatar August 04 / #
Miguel says:

Hey David,

I have this content inside a div that I have a fixed width and height on. Is there anyway to make this work inside a div?

David Walsh August 04 / #
david says:

@Miguel: Take a look at:

http://docs.mootools.net/Plugins/SmoothScroll

I think passing the “win” as the second parameter could work — the win being the div element, of course.

Commenter Avatar August 04 / #
Miguel says:

This is what I have according to the mootools documents. Excuse my “newb-ness”

<script type=”text/javascript”>onComplete.addEvent(‘domready’,function() { new SmoothScroll({ duration: 1800{, win }); });</script>

David Walsh August 04 / #
david says:

@Miguel: Your syntax looks a bit off. Try:

<script type="text/javascript">
window.addEvent('domready',function() {
    var ss = new SmoothScroll({ duration: 1800}, $('scrollingDiv'));
});
</script>
Commenter Avatar August 04 / #
Miguel says:

Hey David,

Thanks for the quick responses. I am assuming the $(’scrollingDiv’));
}); is the name of the div id? Also what is the “$” for? I am not using any backend language.

David Walsh August 04 / #
david says:

@Miguel: Yes, the div id should go in the “scrollingDiv” spot. And the $(”) selects that specific DIV element.

Commenter Avatar August 04 / #
Miguel says:

For the life of me this is not working. I want it to scroll within the div and not the body of the page. Check it out. http://cm.sirs.com/cms/MLKsmall/index.html

David Walsh August 04 / #
david says:

@Miguel: You page is password protected so I can’t look at it. Perhaps the following page would be better:

http://docs.mootools.net/Plugins/Fx.Scroll

Commenter Avatar August 18 / #
coleen says:

Hey David,

This works great…except (as with all the other smooth-scrolling scripts I’ve tried) that something in the js interferes with lightbox.js, another script I’m using on my site.

Could this be a quick fix (renaming something?)?

Thanks,

Coleen

David Walsh August 19 / #
david says:

@Coleen: Unfortunately there’s no quick fix. Moo and Prototype don’t play nice in the sandbox.

Commenter Avatar August 31 / #
Corey Klemow says:

ADI and Dan: Safari sometimes doesn’t like empty anchor tags. Try wrapping the anchor around some text, a graphic, or even just an   – chances are that will clear up your Sarari woes.

If that solves your problem, then you’re simply running foul of a bug in Safari; it has nothing to do with this keen-o scrolling script. I ran into a similar problem a few months ago when trying to use anchor links to navigate an overflow div.

Commenter Avatar August 31 / #
Corey Klemow says:

Whoops, forgot to use code commenting… “some text, a graphic, or even just an &nbsp;” is what it shold say above…

Commenter Avatar August 31 / #
Corey Klemow says:

Hi – regarding the code Joshua and David were talking about on April 1 (hmmm… April Fools?) :) …anyway, am I interpreting correctly that the code is meant to allow you to link to an anchor from another page, start by displaying the page’s top, and then, after a pause (2 seconds in the above example), begin to scroll to the selected anchor? If so, I can’t get it to work… I’m still just jumping directly to the anchor as soon as the page loads. I tested in IE7 and Firefox 3. Can one of you please post a link to a working example? Thanks!

Commenter Avatar August 31 / #
Corey Klemow says:

Sorry to flood this post with comments, but is it possible for the scrolling action to be triggered if the scrolling page is in an iframe and the link to the anchor is on the parent page?

Commenter Avatar September 07 / #
evi says:

Hi David,

thanks for the great tut!
I have a problem with it – it’s working great, but somehow it kills my jquery contact form…

can you look at it in your free time please?

http://www.evidesign.com

thanks!

Commenter Avatar September 07 / #
evi says:

false alert…or not that false, but instead of mootools, I used jquery script..
it’s working now..

THANKS again :)

Commenter Avatar October 09 / #

Hey David,

Thanks for this. Its kind of my first foray into js.

My trouble is that i’m trying to use Lightbox 2 on the same page as the smooth scroll. I actually switched it over to Slimbox in hopes they’d play nicer together since they both use moo as the framework.

Anyway, they don’t play nicely together. 1 or the other. I’m sure its because they are fighting over the anchor tags. Is there any way to produce harmony between these two?

THANK YOU SOOOO MUCH!
Jace

Commenter Avatar October 15 / #
Jim says:

I was wondering if there is a fix for the smooth scroller for Opera or Safari. It works great in Firefox, haven’t tested it in IE yet. But I get the same problem as I’ve read before: it pauses for 2 seconds then just jumps to the anchor in Safari and Opera. When I click the link to the “top” it just jumps without the pause. Thanks a lot.

Commenter Avatar October 19 / #
Alan says:

I am having a similar problem using smooth with lightbox, but I noticed on a website I made for a local foundation using the wordpress theme K2, which uses a type of smooth scroll for scanning threw achieve posts, does not interfere with lightbox.

I don’t know much of anything about javascript beyond using these nifty little plugins, other wise I would dig into it looking for an answer. But I thought maybe someone here would be interested in making these two popular scripts compatible. I would personally appreciate it ;)

Commenter Avatar October 19 / #
Alan says:

Hey thanks Jace Hirschi, I don’t know what you did but I copied and pasted the combined script file from your website and used < div> instead of < a> to set the anchors and everything works fine.

Commenter Avatar October 31 / #
patience says:

Thanks for the great examples… I have been searching for atleast a week and a half for this type of example. I found it about 10 hours ago and I have yet to succeed. I have read over everyone’s comments and followed links and suggestions. I am not sure as to what could be the issue for me…Any comments, suggestions, or links to tutorials would be greatly appreciated.

http://www.annseale.com/v4.html

Commenter Avatar November 10 / #
July says:

Regarding question of “how you could get this to work on page load?”. First make anchor invisible, i.e. style=”display:none” – that’s way browser won’t navigate to the anchor on startup :)
Next, on the onload event repair display property, lets say, to display:block and use SmoothScroll as described :)

Commenter Avatar December 04 / #
Simon says:

Hi David

Thanks for this great script, it is working perfectly just putting a bit of code in the page!

However, I just noticed a small problem I am facing, on one of my pages I have a tabbed content area, and the script seems to be effecting this aswell (obviously as they are anchors too, #tab1, #tab2 etc).

Any way to get around this as all these elemnts need an ID?

Thanks

Commenter Avatar January 21 / #
Jenn says:

Great stuff David!

Thanks for sharing your script with us, I can’t wait to use it!

Commenter Avatar January 28 / #

Hi,

Can we simultaneously use two modules in .html page? I have successfully implemented “MultiBox” & also “Smooth Anchor” (both uses mootools) on separate .html pages. When both are in same page (MultiBox” & “Smooth Anchor”), MultiBox stops working, where as, Smooth Anchor is working fine.

Please help me, Thanks in advance.

Syed Haroon

Commenter Avatar February 13 / #
Cat says:

I’d love to see a how-to for setting up a ‘top of page’ just like you’re using currently (The Top Of Page link is only shown once the user scrolls down and then fades away with an animation when back in start position). Can you write one up please? :)

Commenter Avatar March 29 / #
Zimba says:

Great unobstrusive script, but how can I get it to scroll until the anchor is at the bottom, instead of the top, of the page ?

Thanks a lot

Commenter Avatar April 07 / #
Neil says:

I’m trying to get this working and I’m having problems… on the following page…

http://audiowhispers.org/test/index2.htm

for some reason it works on the ‘Back to the Top’ links, but when I click on the links to go to each section it seems like it tries to scroll up the way…?

any help would be appreciated…! I’m a total beginner at this so be gentle..!

Commenter Avatar October 05 / #
Carlos says:

Hi David!

Nice blog you have. Congratulations!
I´m designing a site in where i use the Smooth Anchors Tool and Lightbox in the same page.

It seems to be an incompatibility between Smooth Anchors and Lightbox. When i open a gallery in Lightbox and clic on “next pic” or “prev pic”, the anchors roll :S

Is there any solution for this? I hope you can find it.

Thanks!
Carlos

PS: Sorry for my english.

Commenter Avatar December 01 / #
Colin says:

Hey David,
What are the chances I can use this on a horizontal page, between anchors? I’m very new. I appropriate your site a lot.

Commenter Avatar December 01 / #
Colin says:

appreciate! sorry, and thanks

Be Heard!

I want to hear what you have to say! Share your comments and questions below.

Name*:
Email*:
Website:  


© David Walsh 2007-2010. Contact David Walsh. Powered by the remarkable MooTools javascript framework.