treehouse : what would you like to learn today?
Web Design Web Development iOS Development

Smooth Scrolling

Last updated on:

Performs a smooth page scroll to an anchor on the same page.

$(document).ready(function() {
  function filterPath(string) {
  return string
    .replace(/^\//,'')
    .replace(/(index|default).[a-zA-Z]{3,4}$/,'')
    .replace(/\/$/,'');
  }
  var locationPath = filterPath(location.pathname);
  var scrollElem = scrollableElement('html', 'body');
 
  $('a[href*=#]').each(function() {
    var thisPath = filterPath(this.pathname) || locationPath;
    if (  locationPath == thisPath
    && (location.hostname == this.hostname || !this.hostname)
    && this.hash.replace(/#/,'') ) {
      var $target = $(this.hash), target = this.hash;
      if (target) {
        var targetOffset = $target.offset().top;
        $(this).click(function(event) {
          event.preventDefault();
          $(scrollElem).animate({scrollTop: targetOffset}, 400, function() {
            location.hash = target;
          });
        });
      }
    }
  });
 
  // use the first element that is "scrollable"
  function scrollableElement(els) {
    for (var i = 0, argLength = arguments.length; i <argLength; i++) {
      var el = arguments[i],
          $scrollElement = $(el);
      if ($scrollElement.scrollTop()> 0) {
        return el;
      } else {
        $scrollElement.scrollTop(1);
        var isScrollable = $scrollElement.scrollTop()> 0;
        $scrollElement.scrollTop(0);
        if (isScrollable) {
          return el;
        }
      }
    }
    return [];
  }
 
});

View Demo

Reference URL

View Comments

Comments

  1. Nick
    Permalink to comment#

    Hi,

    I cant get this to work. Could you provide the appropiate HTML to go with this Javascript?

    Its not obviously clear whats needed, as I’ve tried all sorts of combinations of name values and such.

    Any help would be appreciated

    :)

    • There is a Reference URL above with a working example.

    • Nick
      Permalink to comment#

      D’oh! Didnt see that lol

      Will have a go when I get home as I think I’ve spotted where I went wrong.

      Thanks :)

    • This is a little easier to understand but they both do the same thing

      $('a[href*=#]:not([href=#])').click(function() {
          if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') 
              || location.hostname == this.hostname) {
      
              var target = $(this.hash);
              target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
                 if (target.length) {
                   $('html,body').animate({
                       scrollTop: target.offset().top
                  }, 1000);
                  return false;
              }
          }
      });
      

    • Chris’ snippet doesn’t work smoothly with my website in Chrome . But, for some reason, Devin’s works like a charm.

  2. Jarrett
    Permalink to comment#

    I LOVE U!!!! i been tryna find how to do this for months! :-)

  3. Permalink to comment#

    works like a charm.. thanks so much.

  4. Patricia
    Permalink to comment#

    Thank you so much for this script. Took me awhile, but I got it to work!

  5. Permalink to comment#

    The Reference URL is now showing a 404 page. Know anywhere else that has the HTML to go along with the JS? …and preferably in english? :)

  6. Permalink to comment#

    great code, one question,

    I have a sidebar widget for my video, archive and tags this code is interfering with. What is the coding/marker to disable this from happening?

  7. Jon
    Permalink to comment#

    I cannot get this to work for the life of me, I’m following the example perfectly though… Anyone have any ideas?

    • Without a description of your problem, or a URL, no one will ever be able to help.

      One thing I can say is that make sure you are loading the jquery library.

  8. It’s not working on IE8 at my website, I think there is some kind of Bug…
    Could you see it here with IE8? Thank’s

  9. Az
    Permalink to comment#

    Does this work with Left & Right too?
    Just change “top” to “left” ?

  10. William
    Permalink to comment#

    Sweet! Thank you

  11. jamie
    Permalink to comment#

    I got the second method working on my site, but I also tried to get the nav container to follow the page by adding it it the code like this

    $(‘html,body,#nav’)

    So I just added #nav to the selectors here. But it don’t work. The page still scrolls, but the nav container doesn’t follow. Any ideas?

  12. catchatpas
    Permalink to comment#

    Work perfectly

  13. Fumie
    Permalink to comment#

    Hi Chris, this is awesome! Very simple and clean and works really good.

    I was wondering if it is possible to get the hash link in the current URL of the browser window (i.e. http://www.example.com#target3) while keeping the smooth scrolling effect, so the each hash link can be bookmarkable.

    Thanks!

  14. I have slightly altered this scroll down to the page onload? My idea here is in PHP to check the refer and only scroll down the page only if they have clicked a link from the domain. At the moment I have

    $referer = $_SERVER['HTTP_REFERER'];
    		
    if ($referer != "") { 
    	$this->data['scrollTo'] = true;
    }

    website

  15. Thanks for this Chris! I was trying to do this with Jquery.LocalScroll, this is so much easier!! Saved me a huge headache, thanks.

  16. James

    i have a div with width: 100% height: 100% and another div left: 100% width: 100% so the body is 200%, how can i make the scroll move horizontally?

  17. Shaun

    I changed some bits, which you didn’t explain.. like you expect there to be a corrsponding element id an ID the same as the a.href.. so I changed this

    var target = $(this).attr(“href”);
    To
    var target = $(this).attr(“href”).replace(‘#’,”);

    and this
    scrollTop: $(target).offset().top

    To

    scrollTop: $(‘a[name='+target+']‘).offset().top

    PS. Keep up the good work.

    • Lucian
      Permalink to comment#

      Yes, this is a good point – i couldn’t get it to work myself, and didn’t figure out at a first glance, but this is important:
      There also need to exist the elements with the corresponding ID’s with those of the hashes .
      E.G:

      Those using the method :
      <a href=”#test”>go to hash</a>
      and in your code:
      <a name=”test”>try to get here</a>

      This doesn’t work with the code above,
      I myself have changed the line:

      var $target = $(this.hash), target = this.hash;

      to:
      var target = this.hash;
      var $target = $j(this.hash).length>0?$j(this.hash):($j(‘a[name='+target.replace(/#/,'')+']‘));

      This way it works with both the ID and the A name=… versions

  18. Hello,

    I’m trying to get this to work but for the life of me cant. As far as I am aware, I’ve check the reference and copied exactly… Any help appreciated.

    http://www.certohost.com/tutorials.php

    Thanks.

  19. Hi,

    I used technique #2 and it seems to only work when I click on about, the work and contact link doesn’t seem to work and I don’t know why.

    thanks

  20. Awesome, works brilliantly. Barely having to do anything. Thanks Chris

  21. Superb, worked like a charm.
    Thanks!

  22. Richard

    Hello..

    Just wondering if you had checked this in Opera… getting some funny results when running some tests… v.nice never the less.

  23. Permalink to comment#

    Hi Chris and co.

    When I use this method #2, my Firefox Developer Toolbar shows a js error as follows:

    Expected identifier or string value in attribute selector but found “#”.

    What am I missing..?

    To help, I am using jquery-1.4.2.min.js, and I’m linking to h2′s with id’s, like so:

    Go to 01
    This is Link 01

    Thanks in advance.

  24. Permalink to comment#

    Sorry, forgot to wrap my code:

    <a href="#link-01">Go to 01</a>
    <h2 id="link-01">This is link number 01</h2>

    Thanks
    Jon

  25. Jack
    Permalink to comment#

    works like a charm! thanks a bunch!

  26. Thanks Chris.
    This worked perfectly in Firefox and Safari, but not in Opera. I have yet to test out IE. Any fix ideas for Opera. It currently jumps to the #tag, no scroll.

    Any know issues and or fixes for IE?

    FYI, I used technique #2.

  27. Permalink to comment#

    Thanks for the post, i’ve been trying to get something like this working for ages. Any ideas how to alter the scrolling speed?

    • Did you work out how to alter the scrolling speed? I’d like to do this too.

    • on the line:

      $(scrollElem).animate({scrollTop: targetOffset}, 400, function() {

      increase/decrease the number from 400 to whatever you want, to achieve the desired speed. For instance, I increased this number up to 1600 in order to achieve the effect I was looking for.

      Thanks for this great code Chris!

  28. i used to grab the local scroll for this function. yours works as good. thank you.

  29. Anthony
    Permalink to comment#
    • Chris
      Permalink to comment#

      Got this one to work straight away after hassle with the jQuery LocalScroll

    • Permalink to comment#

      Thanks for posting that link, I was having a weird problem where on click, the page would start to scroll then half way through it would jump to the anchor. Your edits fixed it up.

  30. Permalink to comment#

    This seems clean and easy!

    I see other people asked as well before.
    I am also trying to find a solution for a horizontal site I am working on.
    Could this be modified to work in that case?
    Any hints would be extremely helpful…

    • Permalink to comment#

      Ok… thankfully that didn’t take too much to figure out.
      Using the second method I used this code and it worked:

      $(function(){
          $('a[href*=#]').click(function() {
          if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'')
              && location.hostname == this.hostname) {
                  var $target = $(this.hash);
                  $target = $target.length && $target || $('[name=' + this.hash.slice(1) +']');
                  if ($target.length) {
                      var targetOffset = $target.offset().left;
                      $('html,body').animate({scrollLeft: targetOffset}, 1000);
                      return false;
                  }
              }
          });
      });
    • Cozza
      Permalink to comment#

      Thanks for this!

  31. Permalink to comment#

    I’ve been testing a bunch of different code for smooth scrolling over the last couple of days and these seem to be the most straight forward and easy to implement. I’m a designer not a coder so the simpler the better. Awesome stuff.

    Just one issue. I noticed Fumie asked about having the hash link appear in the URL and Michal Kopanski pointed out that technique #1 let’s you keep the hash links, while technique #2 does not.

    The problem I’m having with #1 is that I can’t link to the hash links from a different page (e.g. from the home page there’s a link something like “about#sometag”). Is there a way to have the hash links appear using technique #2?

  32. Davide
    Permalink to comment#

    I have external anchor links on my page that doesn’t work anymore when using the script :-(

  33. Chris Coyer for President!

  34. Permalink to comment#

    If you want to prevent that the animations “queue up” replace this line:
    $('html,body').animate({
    with this:
    $('html,body').stop().animate({

  35. alex
    Permalink to comment#

    Yay!!!
    Thank you sooooo much, my website is 10x better looking now and your code was so easy to use!
    xo

  36. Jez
    Permalink to comment#

    This is great but it dont want the top to be the top of the browser….

    I have a fixed header at the top and i want the point it scrolls to, to be the bottom of the header.

    Regardless what i do it will always scroll the anchor to the very top of the browser :(

    Anyway of achieving this?

    • russell
      Permalink to comment#

      I am having this exact same problem.. does anyone have a solution?! I’m using anchors with a fixed header, and when I click on the links to the anchors, it scrolls them up behind the fixed header. I’ve tried a few different things, but alas, no success..

      I will be so thankful for any help!!

  37. Hi all,

    just thought I’d point out that script 1 may cause you problems if you are linking to # anchors on other pages than the one you are on.

    If the link were on the same page then the jQuery works fine.

    If any one knows of a solution for enabling # links to other pages, that would be great !
    Thanks

  38. Permalink to comment#

    Thank you for the script. I just have one question: Why would you not use the anchor text in the URL? Has it any benefits? In my eyes it just makes the user experience less. It feels like working in flash. :)

  39. Chris Beard
    Permalink to comment#

    We use a content management system that sometimes requires anchors within links to other pages. I’d love to be able to switch the choice off but I’m afraid we’re stuck with it !
    Alas, the above two scripts won’t work for links such as this:

    http://www.mysite.com/otherpage.html#someanchor

  40. The first method seemed a bit laborious with the separated function, so I integrated it into the bind command as a callback function. Seems to work perfectly fine, though I’ve only tested it in Chrome and IE7.

    $(document).ready(function() {
       $('a[href*=#]').bind('click', function(e) {
    	e.preventDefault(); //prevent the "normal" behaviour which would be a "hard" jump
           
    	var target = $(this).attr("href"); //Get the target
    			
    	// perform animated scrolling by getting top-position of target-element and set it as scroll target
    	$('html, body').stop().animate({ scrollTop: $(target).offset().top }, 2000, function() {
    	     location.hash = target;  //attach the hash (#jumptarget) to the pageurl
    	});
    			
    	return false;
       });
    });
    • Troy
      Permalink to comment#

      Hello!

      I had a problem with the code above wherein upwards smooth scrolling does not work. I tried your code and it works in Chrome, IE9, FF and Opera! Thank you very much for sharing.

    • Permalink to comment#

      @Chris McClean – Thank you so much for this script! I’ve been trying to find a “linked anchor” script that scrolls the page, but also doesn’t interfere with href’s that have the hash (#) symbol stand-alone within them (as those types of href’s typically are used with other JS functions). You’re brilliant! :)

    • Permalink to comment#

      @ Chris McClean – I’ve got one issue with your JS… When a page’s URL has a trailing slash (e.g. example.com/page/), the page doesn’t scroll. Works fine if the page’s URL ends with ‘.php’ or ‘.html’, etc. Any thoughts on how to get your script to work with the trailing slash in a URL?

      $(document).ready(function() {
         $('a[href*=#]').bind('click', function(e) {
          e.preventDefault(); //prevent the "normal" behaviour which would be a "hard" jump
             
          var target = $(this).attr("href"); //Get the target
                  
          // perform animated scrolling by getting top-position of target-element and set it as scroll target
          $('html, body').stop().animate({ scrollTop: $(target).offset().top }, 2000, function() {
               location.hash = target;  //attach the hash (#jumptarget) to the pageurl
          });
                  
          return false;
         });
      });
      
      
    • david
      Permalink to comment#

      Oh my lord! thank you so damn much for including comments in your script, I am so new to js that there are plenty of times that I just can’t figure out what is doing what. Yours is the first script that was so clearly layed out that I was able to understand what was happening in it. I am forever in your debt… and I want to be best friends! Thank you so much Chris Mclean!

  41. Permalink to comment#

    Many thanks, It was very useful, easy to use and works fine… also thanks to all comments I could improve it to fit it to my web…

  42. Permalink to comment#

    hello and thank you for the nice bit of code,
    i tried technique#1 and it’s well done to update the location as the animation is completed, but the browser back-next buttons act a little strange, it looks as the history is kind of “shifted” by one “event” (all in FF 3.6.10, chrome 7.0.517.44 and IE7 PC) : first hit the back button and nothing happens on the screen but the hash goes back well in the URL field, second time the hash goes back again and the screen now starts to show its previous state but then they’re not matching.
    hmm not sure i’m clearly explaining, anyone understanding my point?
    anyone who got to fix this?
    thanks!

    • I’ve gotten rid of Technique #1 and Technique #2 and presented just a single best-of way to do this. As is, the “back button” in the browser does not work. That is a little outside of the scope of this already pretty bulky “snippet”.

      If you are interested in having the back button work, I’d mess with http://www.asual.com/jquery/address/ and basically use the address change function they provide to trigger a click on the appropriate link when it changes, so back-button-scrolling will work.

  43. Been coming to your site for ages and only just now found the snippets section (duh on my behalf)… they are brilliant!

    One question about this one… is it possible to add easing in to this?

    Thanks mate, Sam

  44. Permalink to comment#

    Hi,

    I would also love to know how to add easing?

    Thanks Chris

  45. dynamicflow
    Permalink to comment#

    hey thanx this code helped us a lot

  46. Chris, thanks a lot! I was messing around with different jQuery plugins and I couldn’t get both (scrolling and enabling back-button/bookmarking) to work at the same time. This just works!

  47. All previous examples require anchors to have id as well as name.
    This does not, and skips animation if it cannot find anchor link:

    $(document).ready(function() {
    	$('a[href*=#]').bind('click', function(e) {
    		var target = $(this).attr("href");	
    		var position = $('a[name*='+target.replace('#','')+']').offset().top;
    		if(position!=0){
    			//prevent the "normal" behaviour which would be a "hard" jump
    			e.preventDefault();
    			// perform animated scrolling by getting top-position of target-element and set it as scroll target
    			$('html, body').animate({ scrollTop: position }, 500, function() {
    				location.hash = target;  //attach the hash (#jumptarget) to the pageurl
    			});
    			return false;
    		}
    	});
    });
  48. Permalink to comment#

    Fantastic script, Chris. It does however cause some conflict when using other effects on the same page (take Lightbox for example). Keep up the good work!

  49. Rubira
    Permalink to comment#
    jQuery(document).ready(function() {
    	
    	var scrollWin = function (selector) {
        	jQuery('html, body').animate({
        	scrollTop: jQuery(selector).offset().top
        	}, 800);
        }
        
        jQuery("[href^=#]").click(function(e) {
        	scrollWin (jQuery(this).attr("href"));
        	return false;
        });
    
    });
    • Giovanni
      Permalink to comment#

      scrollTop: (($(target).offset().top) – 41)

      where 41 is the topbar height.

      thankyou

  50. Bryan
    Permalink to comment#

    I have been experimenting with the script and it is working well, mostly. When I create a “back to top” link referring to an id in the body tag it stops just a few pixels short of the very top — it scrolls (smoothly!) up to maybe 10px short of the very top. Why is this? Thanks.

    • Bryan
      Permalink to comment#

      One other thing. Maybe I missed a solution in the above comments, but the script above does not seem to work in internet explorer. Is there some way to make it scroll smoothly in ie? Thank you.

  51. Sascha Martin
    Permalink to comment#

    Chris,

    thank you for your awesome tutorials and scripts.

    This one worked for me fine and made the side behave beautifully.

    I only discovered, that it doesn’t work inside my select box:

    <form name="example_form"> 
    <select name="example_select" onchange="document.location.hash=this.value"> 										
    <option value='anchor1'>target1</option>
    <option value='anchor2'>target2</option>
    </select></form>

    Do you have any idea for me?

    Thank you in advance!!

    Keep on with your great work,
    Sascha from Germany

  52. Great blog post. Code “just works”!

    Thanks for posting..

    - Sri

  53. Scott
    Permalink to comment#

    Hello everyone,

    I wonder if someone has any ideas about the error that i am receiving in the console:

    $target.offset() is null
    var targetOffset = $target.offset().top;

    I can get the page to scroll down to the correct sections smoothly, but once i click the back to top link, it jumps to the top of the page.

    If anyone has any suggestions to try then please let me know, as it is driving a little bit crazy now :S

    Thanks for any help.

  54. Permalink to comment#

    Im battling with this a bit too…

    I cant get the ‘back to top’ aspect to work in FF….And Fire Bug spits out the following error:

    $target.offset() is null
    Line 29

    The other aspects of functionality work great…although like Scott above this post, it animates once, then snaps after that to whichever link…..

    Any help at all, or suggestions would be greatly appreciated…

    URL for refence: http://varsitypixels.com

    Thanks in advance!

    • Jamie
      Permalink to comment#

      I was getting this error too. Its was happening because i didnt have the anchor id in place. i.e.

  55. Permalink to comment#

    Hey guys, loving this awesome code, but I’m having trouble implementing it into my website.

    I’m sort of a cut/paste beginner at this, I got it working at first, but then after adding some other snippets it doesn’t seem to work.

    Specifically, i’m having trouble with the “back to top” links.
    The first one works, but the links farther down on the page don’t.

    http://www.ed-yu.com/website

    Thanks for any insight!

  56. Lewis
    Permalink to comment#

    To add easing – link to the jquery easing 1.3 pack

    Then substitute the section below

    // Animate to target
    $(scrollElem).animate({scrollTop: targetOffset}, 800, ‘easeInOutExpo’, function() {

  57. Lewis
    Permalink to comment#

    Great script by the way – thanks for sharing!

  58. Love the code! I made a couple changes someone might find use for –

    Using the code in the demo gave a syntax error on FF 4 when it encountered a nonexistant target – the variable target in if (target) { is missing its $ in front.
    Also, replacing
    var $target = $(this.hash), target = this.hash;
    with
    var $target = jQuery("a[name=" + this.hash.substr(1) + "]");
    makes it compatible with existing HTML hashtags.

  59. Brian
    Permalink to comment#

    This works great! Love it!
    Just a quick question: How can I make it scroll up to a certain height, i.e. 50px from the top?

    Thanks!

  60. TPa

    Thanks! Did exactly what I wanted and wasn’t bloated with pointless features.

  61. Caroline

    Any plans to post this on Github? :D (pretty puleeeeez!)

  62. Great script! But its not working on ipad/iphone. Does anyone know any fixes to this?
    Thanks!

  63. Love this script, but I also have the issue above. Not working on ipad/iphone. Any fix for this please?

  64. It did not work on ios safari (iphone,ipod,ipad) form me too, but this shorter code did work everywhere ..and does the same (without showing the hash in URL , but I will fix that).
    I leave it to the jquery experts to find out why…

    $(function(){

    $(‘a[href*=#]‘).click(function() {

    if (location.pathname.replace(/^\//,”) == this.pathname.replace(/^\//,”)
    && location.hostname == this.hostname) {

    var $target = $(this.hash);

    $target = $target.length && $target || $(‘[name=' + this.hash.slice(1) +']‘);

    if ($target.length) {

    var targetOffset = $target.offset().top;

    $(‘html,body’).animate({scrollTop: targetOffset}, {duration:1600,easing:’easeInOutExpo’});

    return false;

    }

    }

    });

    });

    • I so wanted Chris’s script to work for me, but after struggling womanfully for an hour, just couldn’t do it. (Can’t say why it doesn’t work – if I knew that, I’d be able to fix it.) This little alternative, though, works a treat, and it eases. And it doesn’t need the extra id for the target instead of just the name (I gather Chris’ script needs the target element to have an id the same as the destination href but without the hash).

      Thanks.

  65. Works ty!

  66. robbie
    Permalink to comment#

    I would also like to know how to get this to stop scrolling at around 100px from the top.

    Thanks, and great script.

  67. Carlo
    Permalink to comment#

    Can I do this same effect using only HTML and CSS (3)?

  68. Thank you so much for posting this! Just what I was looking for. I used to avoid jQuery because there weren’t enough documented examples for me to feel comfortable implementing it (not much of a JavaScript person) but this is really good. It has a nice smooth effect (as the title states). Thanks again!

  69. Marinel

    Hi! It’s already working but once I put the script on my page, the lightbox won’t work. PLEASE HELP! Thanks! =)

  70. Nice and simple, brilliant as always. Thank you!

  71. Hoyd Breton
    Permalink to comment#

    Righteous. Any idea why it doesn’t function on the mighty iPad?

  72. Alex
    Permalink to comment#

    Have a question? I’m new to jquery and I’m having and issue with Lightbox not working with this code. Are the anchor tags conflicting since both this code and lightbox rely on anchor tags to work? If so is there a way around this?

  73. if you’re getting an error $target.offset() is null …. it simply means you have a link that points to #example but the div id=”example” does not exist in the DOM.

    Replace Line 16 from:

    if (target) {

    to:

    if ($(target).length < 0) {

  74. Permalink to comment#

    Awesome!!! this saves me a lot of time!!
    :-)

  75. Fabio
    Permalink to comment#

    Hi to all. Is it possible to set the duration of scrolling? Actually, it seems really fast …

  76. matt
    Permalink to comment#

    anyone know how I set an offset? I want it to stop scrolling say, 50px above each target.

    • tyler
      Permalink to comment#

      Me too! I have a fixed header above the scrolling page and want the scrolling to stop where the section is still below the fixed header, not behind it! :(

  77. casper
    Permalink to comment#

    great thingy !

    stumbled across it and went to build a page around it immediately :)
    going sideways doe. everything works tipytopy.
    am wondering if its possible for it to scroll in different angles?
    If i lets say get to the 4th page to the left and scroll down half a page per
    example and then want to go to the page on the right (that actually starts half a page
    higher than i am now) of it it goes directly
    right. id love it to go 45 degrees up/right (northeast).
    making sense ? im working around it but its messy.
    would love to know if its doable? tnx a bunch.

    all the best, c

    ps: not necessary 45° , 38° is even better

  78. Permalink to comment#

    Hi,
    I would love to use this awesome script, but somehow it doesn’t work on my page.. Any idea why?
    http://www.sderidder.nl
    cheers!

  79. Permalink to comment#

    I got it to work now, but when i run the w3c validation tool it gives some errors.. http://validator.w3.org/check?uri=www.sderidder.nl&charset=%28detect+automatically%29&doctype=Inline&group=0

    any idea? thanks

  80. Thanks!, not work for me because I have jquery 1.6 and this is for 1.4.

    But is good information. I will try with other solution. Thanks.

  81. Permalink to comment#

    Big thanks for the script!

    The script was failling first because I was using <a name=”foo”> instead of elements with id’s, and secondly it would fail when the target element wasn’t found.

    Changed this:

    
          var $target = $(this.hash), target = this.hash;
          if (target) {
    

    To this:

    
         var target = this.hash.replace('#','');
         var $target = $('a[name='+target+']');
         if ($target.offset() != undefined) {
    

    And it works out of the box with existing mark-up.

    • toricollinsmac
      Permalink to comment#

      I was having problems getting this to work on my site and couldn’t figure out why. But I implemented your change and it works now. Thanks!

  82. Permalink to comment#

    Hej.
    If you guys are using jQuery tabs or any other jquery or anyother script as a matter of fact that also uses the # tag to do something I have a quick fix for that, edit this line:

    $('a[href*=#]').each(function() {
    to
    $('a[href*=#wrap]').each(function() {

    You change the default a[href*=#] by changing the # it targets.
    In my case I do my sliding with the hash tag #wrap …
    So I modified the code so that the scrolling targeted only my wrap thus a[href*=#wrap]

    I hope you folks understand, honestly I don’t at this moment. But it does work. Now my jquery tabs work perfectly along with the smooth scrolling.

    cheers

    • Permalink to comment#

      i tried this, then my scrollTo doesnt work, if there is a way to exclude a set class or id that would work best. you are including from the sounds of it one set of anchors.

  83. Jeff
    Permalink to comment#

    Sweet script, I’m using it on a redo of my portfolio site I hope to put up in the next week. The site is also using twitters bootstrap and I ran into a problem. If I want to use the bootstrap tabs, this code scrolls the page up to the top.

    Bootstraps tabs use anchors and anchor links. So I was wondering if there was any way to set your code to only notice ancor links within a set ID. I’m not a coder so please excuse my ignorance. – Jeff

    • Jeff
      Permalink to comment#

      Doh, Jalokims example works for me too, don’t know how I missed his comment.

      So I changed all my anchors that I want the smooth scrolling on to start with #nav and set that up where Jalokim used #wrap in the JS code. Then I can use #navhome #navgallery and so on for the smooth scrolling anchors and any anchors that don’t start with #nav won’t smooth scroll!

  84. Chris
    Permalink to comment#

    Hey, Great Tutorial. I was wondering how one would offset the scrolling of the div from the top of the browser window to be offset say 150px from the top of the browser – I have a fixed positioned header occupying this space and would like the div scrolling to the top to come just below this.

    Any help would be great!

    • Nick
      Permalink to comment#

      I’d love to know an answer to this as well (I have a fixed header)
      . I’ve tried editing the $target.offset like so:

       var targetOffset = $target.offset().top - 40

      but that doesn’t seem to have much of an effect on things, alas.

    • Gabriel G
      Permalink to comment#

      Insert -40 (or whatever height your header has), but after ScrollTop:targetOffset, not after $target.offset().top – so the code should read:
      $(scrollElem).animate({scrollTop: targetOffset-40}, 400, function()…

    • Permalink to comment#

      I was having the same problem too, and was trying to figure out why the “jerking” behavior happens with the fixed header . This is why—the animated process works in this order:

      First, it animates the screen position to the anchor location by number calculation. Then, it puts the hashtag into the location. So, the code is actually moving the screen twice! You just don’t see it on the second move because it’s already been moved into position!

      However, if you’ve got a fixed header and try to account for it in the offset, you will then see the jerk backwards because it is calling the hashtag position on the second move.

      I have two ways I currently deal with the fixed header issue:

      1. If I must preserve the hashtag, then Stefan in the comments here has a good CSS offset solution.

      2. If I don’t have to preserve the hashtag, then I just remove the call for the hashtag anchor, like this:

      $(scrollElem).animate({scrollTop: targetOffset-60}, 1000);
  85. Eric
    Permalink to comment#

    Hey Chris, fantastic work. I was playing around with the example and was able to minify it as well as tackle some of the “issues” addressed in the comments.

    This code below (based on your work) allows for both same site links with hashes (ie, referencing another article on another page), as well as external.

    For troubleshooting, the $(‘body’) (vs) $(‘html’) would be the first change if this is not working, all else should be good.

    It is also really easy to add the hashes back to the browser address bar, however, it seems better UX wise to leave them off. – that is just my viewpoint though.

    (jQuery 1.7)

    
    $(document).ready(function() {
    	
    	$('a[href*=#]').each(function() {
    		if($(this).attr('href').indexOf("#") == 0) {
    			$(this).click(function(e) {
    			  e.preventDefault();
    			  var targetOffset = $($(this).attr('href')).offset().top;
    			  $('body').animate({scrollTop: targetOffset}, 700);
    			});
    		}
    	});
    
    });
    
    • Nick
      Permalink to comment#

      This solved my problem regarding the offset, and it’s smaller. Thanks Eric! Fingers crossed that their aren’t any issues : )

    • Nick
      Permalink to comment#

      Alas, using “body” for

      $('body').animate({scrollTop: targetOffset}, 700);

      seems to break things for Chrome : ( anybody have any tips?

  86. Lucy
    Permalink to comment#

    I’m working with anything slider v1.5.17. For some reason it’s not playing in Internet Explorer 7. It works fine in 8 and 9 but for 7it only shows the first image and the controls disappear. Am I missing something?

  87. Haldun
    Permalink to comment#

    Thnx alot! it works perfect! but except mobile devices.. Is there a way to make this script works on mobile devices too?

    Thnx!

  88. Hey Chris!
    Fantastic Article one question though,
    How can I reference this in another file, probably a simple thing but I’m sorta a newbie :)

    – Allen Lawson

  89. Permalink to comment#

    See Demo on my site = ajwebdesigner.in

    This works perfectly, just paste the code with jQuery and ready to go :D

    Thanks Chris. !

  90. Heather
    Permalink to comment#

    I’m using the base url meta tag on all my pages and /#top/ would simple redirect me to the homepage.html#top … is there any solution for avoiding that to happen?

  91. Riggs
    Permalink to comment#

    hey there,… im kinda new to code. I have this thing working great in safari but not firefox. any tips?

    Thanks

  92. Permalink to comment#

    Looking for a scrollTo designer for a Business Directory webpage:
    (see) http://www.vtlsuccess.com/Directory.html

    I want (1) an accordion effect to display a Business Directory of Product-Service Categories (4 columns of roughly 25 categories each in the white-center-middle column below the navigation row on the page above. The column-list shown is 1100px L X 227px W).

    Every product-service category name will eventually have an active link that can display details of the exclusive business supplier for that category.
    Visitors to the page will be looking for a provider/supplier of a particular product or service. They first search the alphabetical directory and click the category they’re looking for. (2) The detail information about the provider should be displayed either as a pop-up window in front of the page or in a cell in the right-blue column on the page. I like Ariel Flesler’s “jquery.scrollto” effect for this latter action (see demos.flesler.com/jquery/scrollTo/ and/or http://flesler.blogspot.com/2007/10/jqueryscrollto.html. The displayed information should be printable.

    Once the code and installation instructions for the above capabilities have been provided, I will need to know how to set-up i.e. activate the links and input and/or change information about the suppliers as there will be continual additions and changes.

    I have Dreamweaver CS3 and Photoshop CS5.

    John Hogue
    John@VTLSuccess.com

    Questions:
    Can Accordion Widget work Side-to-side as well as up and down?
    Can Accordion panels contain Links, Lists,Tables?
    Can Srollto. Event occur in separate column from Trigger?

  93. Matt O'Brien
    Permalink to comment#

    I have this working great, with the exception of the “Back To Top” link. It just jumps up with no smooth scroll. Any ideas would be greatly appreciated.

    http://kspersonaltraining.ca/index.v2.html

    Cheers

  94. This is the correct easing code:

    // Animate to target
    $(scrollElem).animate({scrollTop: targetOffset}, 1100, ‘easeOutElastic’, function() {

    I added ‘easeOutElastic’ for a bouncing effect!

    Do not forget to add the jQuery easing pack.

  95. Hi there, I noticed that when I implemented the code that the scroll animation would scroll to the wrong spot and then jump (like a normal href=”#*”) to where it was supposed to go when the window was resized. The issue seems to be that the offset gets determined basically on page load which screws up fluid/percentage based layouts since they reflow and change the actual offset. The solution I end up with was to just calculate the offset on click instead.

    To do so replace this:

    $('a[href*=#]').each(function() {
        var thisPath = filterPath(this.pathname) || locationPath;
        if (  locationPath == thisPath
        && (location.hostname == this.hostname || !this.hostname)
        && this.hash.replace(/#/,'') ) {
          var $target = $(this.hash), target = this.hash;
          if (target) {
            var targetOffset = $target.offset().top;
            $(this).click(function(event) {
              event.preventDefault();
              $(scrollElem).animate({scrollTop: targetOffset}, 400, function() {
                location.hash = target;
              });
            });
          }
        }
      });

    with this:

    $('a[href*=#]').each(function() {
        $(this).click(function(event) {
        var thisPath = filterPath(this.pathname) || locationPath;
        if (  locationPath == thisPath
        && (location.hostname == this.hostname || !this.hostname)
        && this.hash.replace(/#/,'') ) {
          var $target = $(this.hash), target = this.hash;
          if (target) {
            var targetOffset = $target.offset().top;
              event.preventDefault();
              $(scrollElem).animate({scrollTop: targetOffset}, 400, function() {
                location.hash = target;
              });
          }
        }
       });	
      });
    • Elginmarvel
      Permalink to comment#

      Thanks for this Derek.
      I’m experimenting using DropBox to build a html5 site and had the same problem.
      Replacing this piece of code fixed it.
      By the way: this works on a Mac with every browser I can throw at it. Also worked on my Explorer 6 test station. I’m not using php or any other scripts.

      Wonderful work Chris.

    • Taz
      Permalink to comment#

      Thanks Derek. The initial script is great, but if you are building a responsive design, the anchors are slightly off upon changing size. This script fixed it.

  96. Thank you for the example. I realized when I reference a target that does not exist, it fails. Basically your logic to “Ensure target exists” needs a little adjustment.

    I replaced the following

    
             // Ensure target exists
             var $target = $(this.hash), target = this.hash;
             if (target) {
    

    with

    
             // Ensure target exists
             var $target = $(this.hash), target = this.hash;
             if (target && $target.length != 0) {
    

    Now it works every time.

    Thank you!

  97. Permalink to comment#

    i have this working well, except i have some tabbed content as well and since this looks for any anchor # i want to write in an exception. I know enough JS to be able to read it, but not enough to write in my own exception.

    • conualfy

      It is easier than this if you are only interested in the content area of your website. For instance, I have no interest to jump to links in the sidebar, so I changed the source like this:


      var scrollElem = scrollableElement('.span9');//'html', 'body'

      In my example, I am only interested in the div with class span9.

  98. Thank you, thank you, thank you!

  99. johnny_n
    Permalink to comment#

    Yes, very well done — thanks @Tony and @Derek for the tweaks!

  100. Permalink to comment#

    Hi All,
    Not sure if this question has been answered before but how would I modify the script so that it scrolls from a javascript call command to an anchor rather than the a[href*=#]. Some of my pages don’t have straight links but rather javascript calls to an anchor.

    This is a great tutorial but there have been so many comments that it gets hard to follow after a while. Thanks in advance.

  101. johnny_n
    Permalink to comment#

    @Haldun is right — doesn’t work with mobiles, at least iOS…

  102. Geko82
    Permalink to comment#

    Hi i’m trying to insert this fantastic effect in my web site at this page :
    http://www.martinimarmi.it/marmo.html
    my ideas is to set the links in the center-left div and when clicked scroll the center-right div to the anchor. But the metter is that i’m not so good with javascript ( yes! and with english too, sorry), so i ask help to you.
    Please if you have any ideas help me.

  103. Joey
    Permalink to comment#

    I use chrome and opened the Java console and copy pasted the script.
    the error was TypeError: Cannot call method ‘ready’ of null

  104. Permalink to comment#

    Hi All, I am trying to impliment this on my page but cannot get it to work yet. It appears in the head tag when I use firebug (it’s a drupal site and as such I put it into the reference to the file into the .info theme file) however I cannot get it to actually work. I have also flushed the cache. It’s at http://icanw.org.uk/cms/ -if anyone has any ideas I’d be thrilled to hear them – thanks!

  105. Jon Yetter
    Permalink to comment#

    I have a fixed header and its returning #NaN with the following code (but functioning) :

       $('a[href*=#]').each(function() {
        var thisPath = filterPath(this.pathname) || locationPath;
        if (  locationPath == thisPath
        && (location.hostname == this.hostname || !this.hostname)
        && this.hash.replace(/#/,'') ) {
          var $target = $(this.hash), target = this.hash;
          if (target) {
            var targetOffset = $target.offset().top - 220;
            $(this).click(function(event) {
              event.preventDefault();
              $(scrollElem).animate({scrollTop: targetOffset}, 600, function() {
                location.hash = target - 220;
              });

    Any thoughts on how I could get the desired effect without the NaN?

    • Jenn
      Permalink to comment#

      I’m having the weird #NaN issue, too. I hope there is a fix for this. What a bummer, the offset trick is working beautifully otherwise!!

      I’m using Derek and Tony’s modified code, if that helps troubleshooting any…

  106. Stefan
    Permalink to comment#

    Hello everybody!

    Like this script very much well done! It work fine on my static page, but now im trying to us the script on a wordpress installation. And won’t get this to work. This kind of the “$” and jQuery concflict, but not exactly i think… I tried to replace all the “$” in the script with “jQuery” and it didn’t work either… I ididn’t expect it to though. Lines like ” $scrollElement = $(el); ” are also causing conflicts… So my question where exactly do i have to change the “$”? Or is there another solution fpr my problem? I tried no conflict but didn’t work…

    BTW I had that fixed header problem as well. My solution was to give the anchor a class “goto” and then style it with display:block; a padding with height of my header and a negative margin with that same height. Like:

    a.goto { display: block; margin: -69px 0 0; padding: 69px 0 0; }

    The padding would then push my content beyond the fixed header at the top of the viewport, and the negative margin “negates” the block display, so that everything is still in place. Hope that helps…

  107. Permalink to comment#

    Works like a charm. Thanks you much. Worked immediately for me :)

  108. Permalink to comment#

    Can this be used for commercial purposes i.e. for a corporate website?

    Thanks

  109. Jasmin
    Permalink to comment#

    Hi, this is jasmine. Today i met with a problem. My table is being moved up when i use the firebug in my webpage. Currently am working in eclipse. Can anybody help me to sort this out?

  110. Thanks to Derek!

  111. Hi there. Excellent snippet!!
    Just one change to make: when the link grabbed points to something (an object) that doesn’t exist in the DOM, it crashes.
    The solution is to check if the object you point-to really exists. To make this happen, just change the ‘if’:

    if (target) {

    to

    if ($target.length) {

    Solved.

  112. lukasz_p
    Permalink to comment#

    Great snippet!

    And I found solution for header “bug”. Variable target is a string so you cannot contract from it. So instead changing hash in callback function, simply do if after animation.

    
    		if (target) {
    			var targetOffset = $target.offset().top - 120;
    			$(this).click(function(event) {
    				event.preventDefault();
    				$(scrollElem).animate({scrollTop: targetOffset}, 400);
    				location.hash = target;
    			});
    		}
    
  113. lukasz_p
    Permalink to comment#

    Ok, there was problem with scrolling after hash change in previous solution for header “bug”. Here my new fix:

    
    			if (target) {
    				var targetOffset = $target.offset().top - 120;
    				$(this).click(function(event) {
    					event.preventDefault();
    					$(scrollElem).animate({scrollTop: targetOffset}, 400, function() {
    						$(target).attr('id', 'tmp');
    						location.hash = target;
    					});
    
    				});
    			}
    

    It works, but can sombody explain my why traget id change back to original after callback function? I thought I will have to do it manually.

    • Angie
      Permalink to comment#

      This works! Just add the desired value after “top” then add:

      $(target).attr(‘id’, ‘tmp’);

      after the animate line!

      THANK YOU!

  114. Permalink to comment#

    Hi there.. I am using this scrolling in my container(centered on page). I have a pinned(fixed) menu on the left of the screen. AIf I take the window to a smaller size, and I pick a menu item it scrolls down and then left over my menu. I it posible that this is because of the scrolling? IF yes, how can I disable it?

    Thanks.

  115. Tom DUrkin
    Permalink to comment#

    Love this effect but have noticed a bit of a usability problem with it. I implemented it in to a client website and then noticed that if you want to navigate using the BACK button it starts going though all the anchors that you have used which is quite annoying.

    Would be awesome if there was a solution to this whereby people could still leave the page with one click on the ‘back’ button after using them.

    Anyone got any ideas?

  116. lukasz_p
    Permalink to comment#

    Hi Tom,

    Only thing You have to do is to remove fallback function for animation. So instead:

    $(scrollElem).animate({scrollTop: targetOffset}, 400, function() {
                location.hash = target;
              });

    you write:

    $(scrollElem).animate({scrollTop: targetOffset}, 400);

    Anyway, I think that registering anchors is more userfriendly, couse it’s imitate page by page navigation, if You know what I mean.

    Hope that help.

    • Tom Durkin
      Permalink to comment#

      Thanks a lot of that! I think it depends on how its implemented. I can see instances where cycling back would work and instances where it wouldn’t.

      Either way its good to know that this can be done if needed :)

  117. Permalink to comment#

    Thanks Chris, works perfect.

  118. Marco
    Permalink to comment#

    This script is very close to working for me but I have two variables not resolved. Could someone provide a concise script with these options built-in? I’m sure it would help a lot of other people that I’ve read on many other sites looking these same requirements.

    1.) I need to target links by class to avoid the script breaking other features on the pages.

    2.) My anchors on this wiki do not use an id, but rather – name=”my link”

  119. Chris Dawson
    Permalink to comment#

    If anyone is interested have a look too at this new template – Slidexy – we’ve put together: http://www.tallhat.com/templates/slidexy/ – it uses jQuery and also is responsive as it also presents the same content well on iPhone and iPad.

  120. Marco
    Permalink to comment#

    I found that this script called jQuery.LocalScroll works within the parameters I outlined above. It does not appear to handle headers that have more than common alphabetical letters, so commas, question marks, etc will make it revert to default anchor link teeth-jarring movement.

    I like the script on this page very much, but for this big wiki I’m working with I just could not get it to function without targeting link classes or parent container and using name=link” on anchors rather than id=link”. I will return to use this script on other projects someday and will happily make a donation too -

  121. eaglejohn
    Permalink to comment#

    If anyone has a fix to let this work on an iPad as well, please let us know!

  122. Permalink to comment#

    Perfect, this is just what i’ve been looking for.

    Is it possible to combine this with other jQuery plugins to speed up load time? (without breaking the code)

  123. RP
    Permalink to comment#

    How do we get this to work on an iPad? Thanks!

  124. Your code fails in a couple of browsers (IE, Chrome and Safari … FF seems okay) if they’re zoomed out. It appears to be because of how you check to see if the container is scrollable. The following lines seem to be the issue:

        $scrollElement.scrollTop(1);
         var isScrollable = $scrollElement.scrollTop()> 0;
    

    I’m guessing when the browser is zoomed out, scrolling by one doesn’t scroll at all (which, funny enough, makes 1 NOT more than 0). Changing to 2 will probably fix the issue well enough.

  125. I just read this webpage: http://djpate.com/2009/10/07/animated-scroll-to-anchorid-function-with-jquery/

    and found I can do this with the following code:

    function goToByScroll(id){
    $('html,body').animate({scrollTop: $("#"+id).offset().top},'slow');
    }

    it’s a little bit smaller than yours, I’m wondering what yours does which this doesn’t

  126. Excellent Post, Works Great… I have applied to my blog..

    Check it out here at “YourBloggingTips – Smooth Anchor Linking”

    I have applied both the methods, one provided in the post & other from “Reference Url – Page Source”

    Both seems to work properly.

    The changes I have made to scrolling speed, target.offset & small changes to // Ensure Target Exists

    Following is my complete modified code which works 100%

    
    $(function() {
    	
    function filterPath(string) {
    return string
    .replace(/^\//,'')
    .replace(/(index|default).[a-zA-Z]{3,4}$/,'')
    .replace(/\/$/,'');
    }
    	
    var locationPath = filterPath(location.pathname);
    var scrollElem = scrollableElement('html', 'body');
    	
    // Any links with hash tags in them (can't do ^= because of fully qualified URL potential)
    $('a[href*=#]').each(function() {
    	
    // Ensure it's a same-page link
    var thisPath = filterPath(this.pathname) || locationPath;
    if (  locationPath == thisPath
    && (location.hostname == this.hostname || !this.hostname)
    && this.hash.replace(/#/,'') ) {
    	
    // Ensure target exists
    var $target = $(this.hash), target = this.hash;
    if (target && $target.length != 0) {
    	
    // Find location of target
    var targetOffset = $target.offset().top;
    $(this).click(function(event) {
    	
    // Prevent jump-down
    event.preventDefault();
    	
    // Animate to target
    $(scrollElem).animate({scrollTop: targetOffset-150}, 1600, function() {
    	
    // Set hash in URL after animation successful
    location.hash = target;
    	
    });
    });
    }
    }
    	
    });
    	
    // Use the first element that is "scrollable"  (cross-browser fix?)
    function scrollableElement(els) {
    for (var i = 0, argLength = arguments.length; i  0) {
    return el;
    } else {
    $scrollElement.scrollTop(1);
    var isScrollable = $scrollElement.scrollTop()> 0;
    $scrollElement.scrollTop(0);
    if (isScrollable) {
    return el;
    }
    }
    }
    return [];
    }
    	
    });
    
  127. Jeremy
    Permalink to comment#

    AWESOME ! thanks a lot it helps me for a project !

  128. Permalink to comment#

    Hi all, for some reason I can’t get this to work on this site and page in particular: http://milemarker.com/?page_id=1060
    Any help would be much appreciated.
    Thanks!

  129. Nathan
    Permalink to comment#

    Awesome, thank you!

    One question though:
    I’m designing a website that has a fixed position top bar, so when you scroll down the page it stays at the top of the screen. This means that when I direct to a certain part of the page, say a line of text, it is hidden by the top bar. Is there anyway to offset the scrolling destination a number of pixels so the part of the page I want the user to see is not hidden by the top bar?

    I hope that all makes sense.
    Thanks in advance!

  130. Hey chris do you know how to get the hash mark from appearing at the end of the url. I doont want nothing to be added to the url if its a has bookmark link. If you know the code please tell me where in the above code would i place it

  131. Merisa

    Oh my, thank you so much ! I was wondering if anyone would have the good lines of this function, but yours works ! It’s such a relief !

  132. Eric
    Permalink to comment#

    Thanks so much. Implemented on the page I am currently working on and it looks fantastic!

    One quick question though, if I may.
    How can I have the target ID name (hash) NOT to be displayed in the URL? Is there a way?

  133. william malo
    Permalink to comment#

    I made something like this a while ago:

    
    		//function that returns element's y position
    		var gety=function(a,y){y=0;do{y+=a.offsetTop}while(a=a.offsetParent);return y};
    		
    		$("a[href*=#]").each(function(h){
    
    			if(h=this.hash)
    				this.onclick=function(){
    				$(document.body).animate({scrollTop:gety(document.getElementById(h.substring(1)))},400,function(){location.hash=h});
    				return!1;
    				};
    			
    		});
    
    • Ajmal Afif
      Permalink to comment#

      Hey there, thanks for sharing. This is genius!

      This works with responsive site, in real time too. The solution posted doesn’t work upon browser resize for responsive design (w media queries) but yours worked! Thanks again!

    • Ajmal Afif
      Permalink to comment#

      Ah btw I am trying to achieve something to “push” the target location by, say 120px, like this:

      
      $(scrollElem).animate({scrollTop: targetOffset-120}, 400, function() { location.has = target;});
      

      The current layout i’m using is blocking my h1, it’ll be nice if it can “pull/push” the end target location with the code above.

    • The original example Chris provided does not work with Safari 6.0.3 for OS 10.8.3, but this one you’ve posted above totally kicks butt and even has the hashtag bizness. Way cool! Thanks for posting this!

  134. Hi thanks this is great stuff.

    When i view my site on an ipad sometimes the scrolling works and sometimes it does not. Have others experienced this?

    Any suggestions to get around it?

    The site i am building is

    http://www.risrani.com/newsite/risrani.html

  135. Brian

    You could also change:

    $(‘a[href*=#]‘).click(function() {

    To:

    $(‘a[href^=#]‘).click(function() {

    So that the anchor tag’s attribute “href” starts with rather than just contains a hash.

  136. Ajmal Afif

    Hi there,

    I have the same issue on the ipad as you mentioned. It worked with major delays on my end. Not sure what caused it but i’m looking for alternative too.

  137. Santiago

    Hi, the code seems to work fine if your click an anchor and then you go all up of the page and click another, but if you want to navigate anchor by anchor without going to the top it’s a disaster

    How do I do to make it work like in this website: http://happycog.com/ ?

    • bluesky
      Permalink to comment#

      Also wondering how to get it to work like happycog.com – but compatible with iphone/ipad. Any help or direction would be great! Thx.

  138. Peter
    Permalink to comment#

    Having issues. I am new to jquery and I am using the code as it was displayed in the tutorial. Come to find out the client is pulling my page in with an iframe. Is there alterations to be made to the code to make it work or is it borked from the get go? Ifthere alterations anyone have any ideas to what those might be? Thanks in advance. I sincerely appreciate it.

    $(document).ready(function(){
    $(‘a[href*=#]‘).click(function() {
    if (location.pathname.replace(/^\//,”) == this.pathname.replace(/^\//,”)
    && location.hostname == this.hostname) {
    var $target = $(this.hash);
    $target = $target.length && $target
    || $(‘[name=' + this.hash.slice(1) +']‘);
    if ($target.length) {
    var targetOffset = $target.offset().top;
    $(‘html,body’)
    .animate({scrollTop: targetOffset}, 1000);
    return false;
    }
    }
    });
    });

  139. I’m using the plugin from the refence link and I can’t get it to work: I’m have a Scroll/Follow Sidebar (from here http://css-tricks.com/scrollfollow-sidebar ) whose links I want to have the smooth scrolling applied. It works returning up, but it won’t work going down (the links don’t work at all..)
    Here is the file http://cl.ly/3h3i3p0h0m34191F0T2h

    Can someone help me figure this out? Thanks in advance

  140. Peter
    Permalink to comment#

    Plugin is not working in the newest Safari 6.0 (Mountain Lion)

  141. Chorny.s
    Permalink to comment#

    if i want to add scrolling efect like “easeOutExpo”
    where should i put it, and if i can ?
    btw grate jquery, realy usfull :)
    loved it!

    Chorny

  142. Amazing. Thank you so much.

  143. For some reason…This no longer works in Safari 6.0 after the Mountain Lion Upgrade.

  144. Ajmal Afif
    Permalink to comment#

    Thanks for confirming this. Perhaps somebody with a workaround or solution might jump in and save the day.

    I don’t have Mountain Lion so I can’t even try.

  145. Yepp. Mountain Lion spoils it! Cant nail the reason…

  146. Ok, seems not to be a code problem, rather a buggy Safari:
    https://discussions.apple.com/thread/4145775?start=0&tstart=0

  147. Visualis
    Permalink to comment#

    Just posting to keep updated.

  148. Permalink to comment#

    I love this smooth scrolling, it works for me fine without any problem. Thanks a lot for such good scrolling.

  149. Anyone able to get this working on Safari 6.0 ? Or at least a way to have normal anchor (jump t0) functionality work?

  150. Permalink to comment#

    This seems to have stopped working in some versions of Chrome. Any advice?

  151. Permalink to comment#

    bug in Safari. 50% solution – url changes do not work

    jquery upgrade to 1.8

    arrange for the smooth scrool ios

    
    $(function(){
    
    $('a[href*=#]').click(function() {
    
    if (location.pathname.replace(/^\//,/"\//) == this.pathname.replace(/^\//,/"\//)
    && location.hostname == this.hostname) {
    
    var $target = $(this.hash);
    
    $target = $target.length && $target || $('[name=' + this.hash.slice(1) +']');
    
    if ($target.length) {
    
    var targetOffset = $target.offset().top;
    
    $('html,body').animate({scrollTop: targetOffset}, {duration:1600,easing:'easeInOutExpo'});
    
    return false;
    
    }
    
    }
    
    });
    
    });
    
  152. Here’s a good explanation by Johnny to the bug mentionned above:

    There is a related bug in Safari 6:

    When you insert an element into the DOM, you can no longer immediately do “container.scrollTop = container.scrollHeight”; it will not scroll to the absolute bottom, and will instead stop a few pixels shy, such as scrolling down to 877 pixels rather than 880 pixels. The error gets larger the more elements are in the DOM.

    .scrollHeight immediately updates properly; it’s the .scrollTop property which can no longer scroll immediately down to the new bottom, and clamps the value to some pixels before the end, if called too soon.

    The solution is to insert a small wait period, like this:
    - Insert the new element into DOM.
    - setTimeout(function(){container.scrollTop = container.scrollHeight;},1)

    This will insert a millisecond (plus some overhead) of wait before the .scrollTop change attempt, and is enough to fix the bug. The bug appeared in Safari 6 or the last Safari 5 version.

    I think it’s related to Apple doing all kinds of optimizations (as usual) on their very fast Javascript engine, and somehow screwing something up in the process.

    This comment was posted on Safari 6 breaks my JavaScript.

  153. Michael
    Permalink to comment#

    Hi, well done for your script I need to works from an external link is there any solution, when page loads get that effect.

  154. Permalink to comment#

    This is really great, and I managed to get it working perfectly it seems even though I don’t understand a single thing of javascript. However, I’ve just also used this navigation technique that uses an anchor and so creates a delay when the reveal nav button is pressed as the hidden menu thinks it is meant to be scrolling.

    This is a wild stab in the dark, but do you know a simple method of excluding a particular anchor tag?

  155. Hi,
    This is a great Snippet, but recently i found an issue with Safari.
    Safari doesn’t recognizes the anchor tags named with “id”, just with “name” attribute.
    But the script doesn’t work with this method, so in Safari the anchor’s didn’t work.

    Someone found any solution?

    Thanks everybody.

  156. Just signed up for updates. Going to play with this technique when I get home.

  157. Trevor Briggs
    Permalink to comment#

    I’ve got a similar question to Sascha’s above. This script works fine for all the hard-coded anchors on my page, but I also have a “Find” button using this script:

    function jumpToAnchor() {
    window.location.href = String(window.location).replace(/#.*$/, “”) + ‘#’ + document.getElementById(‘findname’).value;
    }

    and this markup:

    select name=’findname’ id=’findname’ class=’selectOne’
    input type=”button” value=”Find” onClick=”jumpToAnchor()”

    and this doesn’t do the smooth scrolling but jumps directly to the link. Is there a way to incorporate smooth scrolling into this logic?
    Thanks for any help.

  158. Permalink to comment#

    This looks like a pretty bigger crunch of code to actually target and have a smooth scroll on the page…, this is what i would have done to make the smooth scroll….

    $(document).ready(function() {
    $(document).scrollTop($(“div.wrapperBlock”).offset().top); /This would be wrapper of the page/
    $(“ul.nav li a”).click(function(){ /Here you can edit your HTML CSS Structure/
    var endPoint = $(this).attr(“href”).replace(“#”,”");
    var target = $(“a[name='"+endPoint+"']“);
    if (target.length)
    {
    var top = target.offset().top;
    $(‘html,body’).animate({scrollTop: top}, 1000);
    return false;
    }
    return false;
    });

    And the HTML would be

    About

    Definitely would you have done has a meaning behind it, however i would prefer this simple code.

  159. WAY too much code for this functionality.

    Here, check this post out, only 4 lines of jQuery do the same magic: jQuery: Smooth Scrolling Internal Anchor Links – By Charlie Evans.

  160. apoorva
    Permalink to comment#

    appreciate for your work and really nice resource on your site ………

  161. ipunk
    Permalink to comment#

    why cant you provide a plain page with only the necessary code.. without external links; link to homepage, ads and stuff.. so confusing!

  162. Megan
    Permalink to comment#

    I’m having trouble implementing this code. It’s interfering with Bootstrap’s Carousel. I wrote a longer post on this in the forums, but I thought I would ask my question here too. When I click on the arrows in my carousel, the page jumps down to the top of the carousel. Also, the URL changes to “mydomain.com/myproject/#mycarousel.” How can I stop the page from jumping and the URL from changing? Thanks for your help.

  163. lauren
    Permalink to comment#

    Locally, this was working perfectly. However, now that my website is online, occasionally the smooth scrolling doesn’t work. When I click the links, it just does nothing. Then when I refresh, it’s fine… any ideas as to why?

  164. Nick
    Permalink to comment#

    Fixed link…
    kswedberg’s github smooth scroll

    Cross broswer, great options.

  165. Juan Garcia
    Permalink to comment#

    Hola muchas gracias, funciona 100%. Mi pregunta es y si quiero que se desplace horizontalmente como se puede lograr esto? Gracias

    • Juan, el plugin que menciona Nick debajo, kswedberg’s github smooth scroll, parece tener la opción de hacer scroll horizontal de acuerdo a lo que leo en la documentación: direction: 'top', // one of 'top' or 'left'

      No sé si sea eso lo que estés preguntando.

      PD. De arepa yo sé Español, pero te recomiendo que siempre postees en Inglés, así sea machacado, no importa. Es la manera más eficiente de recibir ayuda.

  166. Hi, do you know if this works in IFRAMES?

  167. Andreas
    Permalink to comment#

    Can I use this code snippet for commercial purposes as well?
    Thanks in advance for an answer.

    Best regards

  168. Permalink to comment#

    Chris’s code works well, however the shorter code by Devin Sturgeon and Weremoose etc… has a noticable performance lag on all other links when initialising the Firfox(PC) window.

  169. Permalink to comment#

    In addition to the post above I have now discovered Chris’s code does indeed have some lag (but noticeably less). If we target the selector a little more then this completely eradicates the delays on other links. $(‘#header a[href*=#]‘).each(function() { …

  170. Alessa
    Permalink to comment#

    I am a complete novice to web design. Trying to implement the smooth scroll on my site. I have created the anchor links, now just need to include the smooth scroll. Can anyone please provide a step by step on how I can do this please?

  171. Yan
    Permalink to comment#

    Thanks for this.

    Works on my project well!

  172. Jack
    Permalink to comment#

    Thanks a lot! But this doesn’t on Safari (v6.0.2). Can someone help me to solve this?

  173. AWESOME!!!!!!!

    i was searching for this from about last one hour….thank you dude…….

    Your site is best in CSS and jQuery tutorials……i’am fan of you……thanks……… :)

  174. Saurav Chaudhary
    Permalink to comment#

    hi, im not so good with jquery but im pretty good wid css and html i just want a simple thing: a link and when i click it, the page scrolls smooth to a tag h1 with id=”here.” can u please send me a code which i just have to copy and paste and can u add comments as to where i have to write the id or make any changes… pls pls pls i really want this. Please send the code with comments to my email: bornforeducation@gmail.com

  175. Ercin
    Permalink to comment#

    How can i scroll it horizontal? =(

  176. This fixes the Safari issue for Mountain Lion but you have to specify an ID or Class for the trigger.

    <script type="text/javascript">
    jQuery(document).ready(function($) {
    $("#elem").click(function(event){       
        event.preventDefault();
        $('html,body').animate({scrollTop:$(this.hash).offset().top}, 500);
    });
    });
    </script>
    

    Cheers

  177. Rayan
    Permalink to comment#

    Can you please mail me the total demo file please!!

  178. Trent Hogan
    Permalink to comment#

    If anyone is still having trouble with iPad’s and the navigation becoming un clickable after the first click. I have found a hack to get around this problem. You will have to add a div just before the closing tag of the last element or container you are scrolling, then use jquery to set the height to 1px before the animation runs then using a callback on .animate() set the height back to 0px after the animation is finished.

    Code I am using here:

    jQuery('a[href*=#]:not([href=#])').click(function() {
    
        jQuery('#device').css('height', '1px');
    
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') 
        || location.hostname == this.hostname) {
    
        var target = jQuery(this.hash);
        target = target.length ? target : jQuery('[name=' + this.hash.slice(1) +']');
           if (target.length) {
             jQuery('html,body').animate({
                 scrollTop: target.offset().top
            }, 1000, function(){
    
                jQuery('#device').css('height', '0px');
    
            });
    
    
            return false;
        }
    }});
    

    And am placing a div with the id of device just before the end of the content I am scrolling.

    Credit where credit is due I found this solution here:

    http://stackoverflow.com/questions/7826868/fixed-position-navbar-only-clickable-once-in-mobile-safari-on-ios5/10030251#10030251

    after about an hour of searching. I hope this may help someone.

  179. Holy friggin’ comments! Thanks for this! Totally what the doctor ordered tonight.

  180. aj
    Permalink to comment#

    sorry guys, I’m totally new to jquery.

    I embeded the jquery google library link in the head tags.
    I put the provided code between head tag or even after body tag, nuthin worked.
    I simply want when I click on < a href=”index.html#point1″>
    The browser moves slowly to < a name=”point1″>

    Thanks in advance.

  181. Bruno
    Permalink to comment#

    What if I want an external?

    Example: Location index page have a link

    Gallery 06

    Redirects to the gallery page and scroll to id=”06″

    How to keep the anchor link?

Leave a Comment

Use markdown or basic HTML and be nice.