Hey! Before you go too far down the rabbit hole of JavaScript-based smooth scrolling, know that there is a native CSS feature for this: scroll-behavior
.
html {
scroll-behavior: smooth;
}
And before you reach for a library like jQuery to help, there is also a native JavaScript version of smooth scrolling, like this:
// Scroll to specific values
// scrollTo is the same
window.scroll({
top: 2500,
left: 0,
behavior: 'smooth'
});
// Scroll certain amounts from current position
window.scrollBy({
top: 100, // could be negative value
left: 0,
behavior: 'smooth'
});
// Scroll to a certain element
document.querySelector('.hello').scrollIntoView({
behavior: 'smooth'
});
Dustan Kasten has a polyfill for this. And you’d probably only reach for this if you were doing something with scrolling the page that couldn’t be done with #target jump links and CSS.
Accessibility of Smooth Scrolling
Whatever technology you use for smooth scrolling, accessibility is a concern. For example, if you click a #hash
link, the native behavior is for the browser to change focus to the element matching that ID. The page may scroll, but the scrolling is a side effect of the focus changing.
If you override the default focus-changing behavior (which you have to, to prevent instant scrolling and enable smooth scrolling), you need to handle the focus-changing yourself.
Heather Migliorisi wrote about this, with code solutions, in Smooth Scrolling and Accessibility.
Smooth Scroll with jQuery
jQuery can also do this. Here’s the code to perform a smooth page scroll to an anchor on the same page. It has some logic built in to identify those jump links, and not target other links.
// Select all links with hashes
$('a[href*="#"]')
// Remove links that don't actually link to anything
.not('[href="#"]')
.not('[href="#0"]')
.click(function(event) {
// On-page links
if (
location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '')
&&
location.hostname == this.hostname
) {
// Figure out element to scroll to
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
// Does a scroll target exist?
if (target.length) {
// Only prevent default if animation is actually gonna happen
event.preventDefault();
$('html, body').animate({
scrollTop: target.offset().top
}, 1000, function() {
// Callback after animation
// Must change focus!
var $target = $(target);
$target.focus();
if ($target.is(":focus")) { // Checking if the target was focused
return false;
} else {
$target.attr('tabindex','-1'); // Adding tabindex for elements not focusable
$target.focus(); // Set focus again
};
});
}
}
});
If you’ve used this code and you’re all like HEY WHAT’S WITH THE BLUE OUTLINES?!, read the stuff about accessibility above.
Smooth Scrolling in React
James Quick has a nice step-by-step tutorial on how to implement smooth scrolling in React using the react-scroll
plugin:
<Link
activeClass="active"
to="section1"
spy={true}
smooth={true}
offset={-70}
duration={500}
>
I LOVE U!!!! i been tryna find how to do this for months! :-)
works like a charm.. thanks so much.
Thank you so much for this script. Took me awhile, but I got it to work!
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? :)
Made a new reference URL.
I made it !
The JS is changed and the explanation is on the JS file…
http://codepen.io/HZaccaro/pen/zvrgLb/
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?
You can try to use the jQuery noConflict technique. Read about it here: http://api.jquery.com/jQuery.noConflict/
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.
Hi, I’m don’t know anything in JS but if you copy that between
<head>
and</head>
, it will work:And all the elements you want to target must be like that:
It will work I think…
Thanks SquirFly,
Your Code is working Well. I used in wordpress 3.8
Make sure that you place the script above in tags.
I realise this is 5 years late, but… with the more recent version of jQuery (2.2), you’ll need to add quotations in the pseudo selector
i.e. in other words, change this bit:
a[href=#]:not([href=#])
to this:
a[href=’#’]:not([href=’#’])
SquirFly code works great! Thanks!
SquirFly, huge thanks! It worked first try!! =D
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
Does this work with Left & Right too?
Just change “top” to “left” ?
Sweet! Thank you
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?
Is the #nav positioned absolute [relative to body] or fixed? That might be the reason.
Work perfectly
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!
Technique #1 let’s you keep the hash links, while Technique #2 does not.
Both examples work great.
Interesting, I seem to lose the hashlink appended to the URL using both techniques.
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
website
Thanks for this Chris! I was trying to do this with Jquery.LocalScroll, this is so much easier!! Saved me a huge headache, thanks.
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?
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.
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
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.
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
Awesome, works brilliantly. Barely having to do anything. Thanks Chris
Superb, worked like a charm.
Thanks!
Hello..
Just wondering if you had checked this in Opera… getting some funny results when running some tests… v.nice never the less.
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.
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
works like a charm! thanks a bunch!
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.
This is working Perfectly in firefox but showing some errors on safari when using method two any solution or guide. thanks
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:
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!
It’s right there in the script. Look for the “1000” number. Replace it with 1500 and it will slow accordingly. If you make it 500 it will speed up by half.
I also changed the scroll speed up to ‘1500’ . still not working for me.
i used to grab the local scroll for this function. yours works as good. thank you.
Demo Here
http://jsfiddle.net/KRmJG/
Got this one to work straight away after hassle with the jQuery LocalScroll
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.
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…
Ok… thankfully that didn’t take too much to figure out.
Using the second method I used this code and it worked:
Thanks for this!
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?
I have external anchor links on my page that doesn’t work anymore when using the script :-(
Chris Coyer for President!
If you want to prevent that the animations “queue up” replace this line:
$('html,body').animate({
with this:
$('html,body').stop().animate({
Yay!!!
Thank you sooooo much, my website is 10x better looking now and your code was so easy to use!
xo
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?
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!!
Jez (and Russell),
This might be a bit late for a reply. I also use a fixed header. All you need is adjust the position you scroll to. Both Chris’ and Devin’s solutiosn use target.offset().top as the target vertical position. You can subtract from it the height of your fixed header before you do the scroll.
var target_pos = (target.length > 0) ? target.offset().top : 0;
var fhdr = $(‘your-fixed-header-selector’);
var fhdr_height = (fhdr.length > 0) ? fhdr.outerHeight() : 0;
target_pos -= fhdr_height;
if (target_pos > 0) {
$(‘html,body’).animate({
scrollTop: target_pos
}, 1000);
return false;
}
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
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. :)
Curious about the same thing…
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
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.
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.
@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! :)
@ 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?
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!
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…
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.
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
Hi,
I would also love to know how to add easing?
Thanks Chris
hey thanx this code helped us a lot
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!
All previous examples require anchors to have id as well as name.
This does not, and skips animation if it cannot find anchor link:
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!
I too happened to have lightbox in my pages, and the two scripts conflicted. But Rubira’s jQuery script works great alongside the lightbox script.
scrollTop: (($(target).offset().top) – 41)
where 41 is the topbar height.
thankyou
` jQuery(document).ready(function () {
where my point is the id of the element I want to get focused. thank you . your code is perfect.
Thanks so much! his code works perfectly for Joomla 3.x. No need to add more, since the jQuery library already gets loaded by default.
Works beautifully in wordpress. I was having issues with the scrollto borking my nested comments(no idea what the conflict was). This resolved it. I am very grateful. thank you.
You made my day. Thanks for sharing.
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.
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.
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:
Do you have any idea for me?
Thank you in advance!!
Keep on with your great work,
Sascha from Germany
Great blog post. Code “just works”!
Thanks for posting..
– Sri
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.
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!
I was getting this error too. Its was happening because i didnt have the anchor id in place. i.e.
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!
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() {
I tried this and it stops the animation completely. Here is a jsfiddle of the issue. http://jsfiddle.net/VEpgV/
Great script by the way – thanks for sharing!
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
inif (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.
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!
Thanks! Did exactly what I wanted and wasn’t bloated with pointless features.
Any plans to post this on Github? :D (pretty puleeeeez!)
Great script! But its not working on ipad/iphone. Does anyone know any fixes to this?
Thanks!
Love this script, but I also have the issue above. Not working on ipad/iphone. Any fix for this please?
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.
Works ty!
I would also like to know how to get this to stop scrolling at around 100px from the top.
Thanks, and great script.
yeah i’m having the same issue, did you ever figure this out?
Can I do this same effect using only HTML and CSS (3)?
Have the same question here…
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!
Hi! It’s already working but once I put the script on my page, the lightbox won’t work. PLEASE HELP! Thanks! =)
Nice and simple, brilliant as always. Thank you!
Righteous. Any idea why it doesn’t function on the mighty iPad?
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?
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) {
Actually it’s > not <
I guess I got my gt and lt mixed up ;)
thank you, awesome!
Awesome!!! this saves me a lot of time!!
:-)
Hi to all. Is it possible to set the duration of scrolling? Actually, it seems really fast …
anyone know how I set an offset? I want it to stop scrolling say, 50px above each target.
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! :(
The way I’ve done it:
Add
margin-top: -50px
to your anchor elements.Simple solution and works perfectly.
Rather than changing the HTML element, I used
scrollTop: target.offset().top -50
and it worked easily. The scrolled stopped almost 50px above the earlier thing!
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
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!
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
ohw, and it doesn’t work for me in Safari..
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.
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:
To this:
And it works out of the box with existing mark-up.
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!
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
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.
hello Jalokim,
I am facing exactly the same problem, my jquery tabs aren’t working but i did’nt understood the solution you provided. Can you please elaborate the solution to this problem. I am using the following code. Thanks
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
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!
Could you post the solution, i have the issue with the bootstrap’s tabs ?
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!
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:
but that doesn’t seem to have much of an effect on things, alas.
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()…
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:
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)
This solved my problem regarding the offset, and it’s smaller. Thanks Eric! Fingers crossed that their aren’t any issues : )
Alas, using “body” for
seems to break things for Chrome : ( anybody have any tips?
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?
IE7 is old, don’t develop for it
Thnx alot! it works perfect! but except mobile devices.. Is there a way to make this script works on mobile devices too?
Thnx!
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
See Demo on my site = ajwebdesigner.in
This works perfectly, just paste the code with jQuery and ready to go :D
Thanks Chris. !
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?
hey there,… im kinda new to code. I have this thing working great in safari but not firefox. any tips?
Thanks
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
[email protected]
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?
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
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.
This worked for me. But used it with ‘easeInOutExpo’
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:
with this:
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.
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.
Thank you so much for that, Derek.
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
with
Now it works every time.
Thank you!
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.
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.
Thank you, thank you, thank you!
Yes, very well done — thanks @Tony and @Derek for the tweaks!
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.
@Haldun is right — doesn’t work with mobiles, at least iOS…
Chris McClean’s Solution seems to work on both iOs and standard browsers.
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.
I use chrome and opened the Java console and copy pasted the script.
the error was TypeError: Cannot call method ‘ready’ of null
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!
I have a fixed header and its returning #NaN with the following code (but functioning) :
Any thoughts on how I could get the desired effect without the NaN?
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…
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…
The fix via padding works. Thanks for that!
Works like a charm. Thanks you much. Worked immediately for me :)
Can this be used for commercial purposes i.e. for a corporate website?
Thanks
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?
Thanks to Derek!
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’:
to
Solved.
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.
Ok, there was problem with scrolling after hash change in previous solution for header “bug”. Here my new fix:
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.
This works! Just add the desired value after “top” then add:
$(target).attr(‘id’, ‘tmp’);
after the animate line!
THANK YOU!
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.
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?
Hi Tom,
Only thing You have to do is to remove fallback function for animation. So instead:
you write:
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.
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 :)
Thanks Chris, works perfect.
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”
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.
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 –
If anyone has a fix to let this work on an iPad as well, please let us know!
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)
How do we get this to work on an iPad? Thanks!
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:
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.
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
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%
AWESOME ! thanks a lot it helps me for a project !
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!
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!
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
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 !
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?
I made something like this a while ago:
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!
Ah btw I am trying to achieve something to “push” the target location by, say 120px, like this:
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!
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
You could also change:
To:
So that the anchor tag’s attribute “href” starts with rather than just contains a hash.
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.
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/ ?
Also wondering how to get it to work like happycog.com – but compatible with iphone/ipad. Any help or direction would be great! Thx.
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;
}
}
});
});
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 https://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
Plugin is not working in the newest Safari 6.0 (Mountain Lion)
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
Amazing. Thank you so much.
For some reason…This no longer works in Safari 6.0 after the Mountain Lion Upgrade.
I can confirm this. Hopefully will have time to update someday.
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.
Yepp. Mountain Lion spoils it! Cant nail the reason…
Ok, seems not to be a code problem, rather a buggy Safari:
https://discussions.apple.com/thread/4145775?start=0&tstart=0
It seems related to the jQuery .scrollTop() function.
For some reason, Safari 6 scrolls the element correctly with,
but reports an incorrect value right after with,
But most interestingly, Safari 6 will report the CORRECT value if you call the function one more time,
I brushed up a quick and dirty test page to demonstrate this behaviour at http://www.cybmed.com/w/safari6bug.
Thanks for solving this and wow that’s some detailed explanation and solution you have there.
Hope this got fix (by Safari) sooner than later.
Just posting to keep updated.
I love this smooth scrolling, it works for me fine without any problem. Thanks a lot for such good scrolling.
Anyone able to get this working on Safari 6.0 ? Or at least a way to have normal anchor (jump t0) functionality work?
This seems to have stopped working in some versions of Chrome. Any advice?
bug in Safari. 50% solution – url changes do not work
jquery upgrade to 1.8
arrange for the smooth scrool ios
Here’s a good explanation by Johnny to the bug mentionned above:
This comment was posted on Safari 6 breaks my JavaScript.
Hi, well done for your script I need to works from an external link is there any solution, when page loads get that effect.
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?
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.
Just signed up for updates. Going to play with this technique when I get home.
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.
This is a little easier to understand but they both do the same thing
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.
Chris’ snippet doesn’t work smoothly with my website in Chrome . But, for some reason, Devin’s works like a charm.
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.
Works perfect. Doesn’t conflict with Bootstrap Carousel.
Fantastic.
Fixes the Safari issues + smoother scrolling in Chrome. Thank you!!
appreciate for your work and really nice resource on your site ………
why cant you provide a plain page with only the necessary code.. without external links; link to homepage, ads and stuff.. so confusing!
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.
As I mentioned just above your post, try this code instead: jQuery: Smooth Scrolling Internal Anchor Links.
Pulkit Goyal replied to my post saying that the script above doesn’t conflict with Bootstrap Carousel. You might want to contact him vis his website if needed.
Also, you may want to use
(e).preventDefault();
on your function to stop the anchor links from activating.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?
Fixed link…
kswedberg’s github smooth scroll
Cross broswer, great options.
Here’s a fix to get it working in Safari :)
Awesome. Thanks
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.
Hi, do you know if this works in IFRAMES?
Can I use this code snippet for commercial purposes as well?
Thanks in advance for an answer.
Best regards
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.
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() { …
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?
Thanks for this.
Works on my project well!
Thanks a lot! But this doesn’t on Safari (v6.0.2). Can someone help me to solve this?
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……… :)
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: [email protected]
How can i scroll it horizontal? =(
This fixes the Safari issue for Mountain Lion but you have to specify an ID or Class for the trigger.
Cheers
You can use any selector as far as I know, something like a[href=”#], or “.nav a” will have the same use as the original without bloating it with classes ;) But thanks a lot for this snippet, it makes 50% of the project I’m currently doing LOL.
Can you please mail me the total demo file please!!
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:
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.
Holy friggin’ comments! Thanks for this! Totally what the doctor ordered tonight.
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.
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?
Wow, it works right out of the box. I didn’t even have to change a single thing to make it work. Just copy-paste the code right into the site. Impressive!
The scrolling works but whenever it scrolls past another div it stops for a second making it look as though the scroll is lagging. Any solutions?
Has suddenly stopped working with iOS devices – was temporarily working with them this morning!
Anyone had any similar issues?
Thanks a lot. Your code didn’t work right (keeps going to the top before scrolling to the destination), but Devin’s code works perfectly fine with a nice and smooth animation.
Cheers!
I love you, this worked immediately. Just what I needed thanks!
Has anyone else had a problem where the scroll goes about 30 pixels past the specified ID? Love the script though, very nice.
I figured out it was calculating just fine and it actually looks offset cause of a fixed navigation I have on the site. Going to look into offsetting it by a certain number of pixels, sorry for the unnecessary comment.
Did you find a solution?
Hello I have used the JQuery and its working fine except TOP-MARGIN. My website has Fixed Header of 70px, and whenever the page is scrolled – it is hiding behind the fixed header! How & where to apply MARGIN-TOP to the script? Thanks in advance.
I’m currently working on a clients site with a fixed header and this works for me:
Just change ‘-70’ to match the height of your fixed header.
I just copy pasted the code, and it worked! Thank you so much, been looking for this all over.
@Radax: Do a search on the page, and midway through the comments there is an answer to your question – I had the same problem, and I got it solved thanks to
Hi,
It’s working… but…
When I change the height of the browser the scrolling is no longer working. After an CTRL+F5 everything is working again.
How can I fix that (without expecting visitors to press CTRL+F5) ?
Regards,
Bob.
Thanks for sharing. It works great! Is there a way to add in a parallax effect? I could imagine it would be possible by including multiple overlays of Smooth-Scrolling, and adjusting the timing for each to sync, but I’m kind of stuck on where to start.
In addition, how about “swipe” capabilities for tablet devices? I’ve had success using Swipe 2.0 with left and right scrolling, but think Smooth-Scrolling with sticky areas, to stop scrolling to anchor “section”, would be cool. Thanks again.
How do add active class when the link is scrolled to the section?
Thanks man, Really helps me, simple but cool…
@Kawsar: this works for me:
$('a').click(function(event) {
event.preventDefault();
var url = $(this).attr('href');
$("a").each(function(index) {
$(this).attr('class', '');
});
$(this).attr('class', 'selected');
});
Luk, I couldn’t get this to work, how do you add active class? I am using bootstrap nav… any help would be appreciated!
This is what I have:
Hey, this doesn't seem to work for scrolling <b>up</b>: for example if you add a link to scroll from Section Three to Section Two it doesn't work from me. Any ideas guys..?
Worked out of the box. Woo Hoo! :)
You are wonderful I really want to be as good coder as you are. Look up to you!! You are the man… Thank you once again…
It doesn’t work on iPhone :(
Devin’s codes are working perfectly :D
Hi there
I’m using this script with a fixed nav (150px high) at the top of the page. Is there a way to add some top padding to the #anchors using jscript to compensate for the fixed nav? Currently the section headings disappears under the nav. I’m not a jscript coder so have no idea what to add or if its possible!
Thanks v much
Fist – Devin’s code is solid and much more efficient.
Second – This whole thing gets a bit mangled by a bug in Webkit
http://stackoverflow.com/questions/1830080/jquery-scrolltop-doesnt-seem-to-work-in-safari-or-chrome-windows
If you have trouble making things work, read that article. Shog9 presents an easy workaround.
Worked straight out of the box for me after I’ve been looking for two or three hours trying to get all sorts of these to work. I think I have a bruise on my forehead now.
Hi there, I’ve implemented this and it’s working great, but i have one problem, I can’t get seem to get a ‘scroll to top’ link to animate? I’m guessing this is due to not having anything after the hashtag?
The most recent version of this code as seen on this page as of the date of this post (October 2nd, 2013) is working perfectly for me as a copy-and-paste, “it just works” solution for smooth scrolling to anchors on a page. I added it to a few pages on an existing site where anchors were prevalent in a number of key areas — where this functionality was greatly needed to enhance the website visitor experience — and it worked immediately. Very nicely done. Thank you.
I was able to get everything working. When I went to make some changes in my imagery (pngs and jpgs) that I used for backgrounds I noticed that the scroll was a little jerky. Do the page sizes have to be a certain length to work optimally? Any ideas why the “smooth” isn’t so smooth? Thanks.
It works very well. Thanks..
Only thing. If I zoom-in the browser, scroll behaves in a very strange way. But, works great under normal cases.
Hi,
how do I make Chris code to leave the hash in the url? I’ve been trying to figure this out for days.. Thanks
Works perfectly … :)
Nice,
The code is pretty simple and works very well
I noticed the wierd scroll behaviour on zoom-in = /
Thank’s anyway = D
This code don’t work with the latezest version of jquery 1.10.2.
damn !
Chris, Please could you correct the typo in your code:
I believe should be:
Otherwise the page can scroll down to an anchor regardless of the URL path. Been driving me crazy all day that one! Cheers!
You are very correct! Nice catch. Fixed.
Perfect, Thanks !! :) I had to modify to up 80px
This is the animated scrolling code with easing I made for WordPress.(This does not require the jQuery easing pack)
Put this in the Functions.php
Thank you Michael I was trying to figure out how to get this working in WordPress. This worked perfectly (and much easier to implement)!
Well done!
3 notes:
1. It can also be added as a plugin (so you can enable or disable in case you have to debug an issue, and keep your functions.php file neat): 2
2. I would recommend giving a more specific target to prevent issues on the rest of the page. So I’d replace:
with
I would hook it to the footer, I dont think it needs to load in the header add_action(‘wp_head’,’smoothscroll’);
Plugin with instructions: https://gist.github.com/tukano/2e30cc9262da4b45d047a46ffd829adc
Can anyone tell me where I am going wrong here? My brain is wrecked I’ve tried so many different versions and none seem to work.
http://www.kt-testing.co.uk
This is the page, view the code in the source.
Thanks.
Fantastic. I’ve found a lot of people who claim to know the answer, but they didn’t. Yours worked first time perfectly. I’m going to follow you on twitter right now.
Hey,
This is great!
One question, I have a responsive menu at the top of my page, with the ID of #menu, how would one go about excluding this ID from the function? any help would be awesome!
Cheers!!!
The best I’ve used! Thank you so much!
The smooth-scroll does not work on iPad for me. As I understand, iOS usually turns off javascript to save memory. Is there a workaround for iPad? Or do you have a suggestion for a fallback? My regualr href anchors don’t work on iPad when I have smooth-scroll turned on, although they do work when it’s not on. (Love the snippet and works perfectly on desktop!)
http://www.nebraskaaddys.org/dev2/student-submissions.php
i don’t know if someone already mentioned this, i couldn’t find anything in the comments so far.
if the target is just 300px away or if it’s 1500px away the animation time is the same. so i added the following..
var scrollDiff = target.offset().top – $(‘body’).scrollTop();
then used this value for the animation time
yep. the script is great. i have been using it since like a decade.
can there be a way to make it smooth upto a distance and then make it bounce at the end? i once visited a site (couldn’t find anywhere now!) on which they used scroll to top with bounce effect at the top! any sugestions?
try using TweenMax..
http://jsfiddle.net/ZB26f/4/
first of all thanks for answering.
the script was nice, worked with charm.
the problem was its size (99 KB). it would be great if it works by ome small inline script. any suggestions?
Perfectly works! Thanks!
This works very well, till i run into one issue which is using these links with scroll animation in my navigation bar. I have a scroll function that highlight each link’s background while scrolling. When the links are clicked, the background should be highlighted and scroll to the destination. But the scroll animation under link.click function is still a scrolling movement, though no done by human, triggers the scroll function.
So assume there are 10 links on the navi, and i click the last one, you will see the background of 1-10 got highlighted and de-highlighted like a train during the scrolling animation from your code.
What can I do to prevent this? Adding a condition to filter if the scrolling movement is done by human or animation?
Thank you
Feeling good after visiting your site! :-)
MUCHAS GRACIAS !!!! Thanks a lot, very easy and makes my website look classier :)
How do I modify the code, so that it shows the hash at the end of the url? I.e. http://www.example.com/#about-us instead of just http://www.example.com/
Thanks! Here’s a suggestion on how to make the hash visible in the URL after clicking:
I think this behavior is better. It’s closer to the browsers’ default, which should imply that users are less likely to make mistakes (on such things as browser history), and they’ll be able to copy-paste the URL complete with hash and all.
Personally, I’ve also applied these additional changes:
Changed selector: Apply animated scroll only to elements with class “scrollto”. I did this to gain more control and avoid interference with other stuff, like carousels. You can easily modify the selector to fit your specific needs, for example by selecting multiple classes.
Scroll stop point set to 20px above the target. Just feel less cramped. :)
Scroll completes in 500ms. I think this is enough, and seem to recall a usability study found that user-triggered navigation animations (or similar) should complete in 500ms or faster. No time to dig up a reference, but I think it was a study by Jakob Nielsen. (That being said, I kinda like the idea of calculating the time based on the scroll distance (SD), i.e. shorter time for shorter SD, longer time for longer SD.)
If anyone’s interested, here it is:
is this possible to add this js when windows loaded , the js move smoothly to content ?
Thanks for this Chris.
Does anyone know how to force the browser to run this script when the user types a new/different hash on the URL? I notice that it runs on first load. But when the user types a new hash, the browser appears to take over and performs the default action–which is jump straight to the hash location without scrolling at all.
I slightly modified the script because I have a fixed nav on top of my page. So I’m adjusting the position to scroll to. But it is not getting run when the user types a new hash. That may not never happen (a user typing the hash), but I thought it would be nice to also run the script in such case. I’ve seen CSS fixes to adjust margin/padding for such but I do not like that solution (as it was mesing up with the user’s ability to copy/paste text from the page).
Thanks in advance!
Ooops, I found the answer to my question: jQuery has a ‘haschange’ event. Nice!
Hey everyone. For those still trying to get this to work on iOS devices, all you need to do is add a bit of CSS :
-webkit-overflow-scrolling: touch;
Make sure to add it to the style attributes of the scrolling content & you’ll be in business! :)
I added following line in a code to avoid an inappropriate scroll on current hash
Full Code:
thanks man, thats great! working perfectly..
Hi, I don’t know much at all about coding, but I want to achieve this effect on a back to top anchor that I have. Can someone explain the modifications and exactly what I have to do (in detail!!) to make it work?
Any help would be much appreciated.
This smooth scrolling will come handy . Thank you :)
You’re a wizard! Very elegant, thanks again Chris!
How to add this animation on this: onClick=”location.href=’#div'”?
Very good Chris, will use this in the future.
Thanks just exactly what I was looking for worked so I’ve got no problem with it, thanks again, take care.
This doesn’t work, and produces the error ‘TypeError: target.offset is not a function‘.
So, I would like to offset where to scroll stops at the top of the page. I have a fixed nav bar that it keeps hiding under when I navigate to desired sections – Can you please suggest any ideas?
thank you very much, helped me a lot ..
You may find that this JS clashes with Bootstrap.
If so, here is a nice fix:
The first line $(‘a[href*=#]:not([href=#])’) actually looks for all anchor elements which can be optimised using HTML 5 data attributes:
Replace:
$('a[href*=#]:not([href=#])')
With:
$('[data-toggle="elementscroll"]')
Next thing to do is place the HTML 5 attribute on each of your anchor links, like below:
Hope this helps anybody out there!
If anyone know how to extend this code so that I can change the colour of the navigation links or add decoration such as an underline that would be appreciated.__
This worked like charm.
Thanks!!
Is there an easy way to add this code to a separate JS file and then call the function from within the main html?
http://cferdinandi.github.io/smooth-scroll/
This worked best for me. It doesn’t use jQuery.
It took a lot of scrolling to arrive at your recommended solution.. thank you sir, this works a treat for me!
I don’t know if anyone has already posted this solution but I had my links in a fixed footer and the content within a div within the body.
The script above only worked if I was going from the very top of the page to the clicked link, going from one link to the other did not seem to work. I noticed the reason why was because the scrollTop was set to the distance between the anchors instead of the actual offset of the anchor from its parent. So I just took the distance between and added it to the scrollTop of where the user already was and that made everything work just fine.
You’re a Godsend! I have been toiling over this for the last 48 hours, and your code solved my problem! All I had to do was replace the two instances of #myDivWithScrollBar to #content, which was the name of the div I was using, and presto, everything was clockwork.
Thank you SO much for taking the time to post your solution!
my header is fixed and when i clicked it scrll down properly but it get hide behind header which is fixed position on top.
Could you please let me know the solution how to set top position when it scroll down
you should use: top-your header height, for example top-60..
top -100 in this smoothscrool.js works indead perfectly, (sooo happy I found this) but only on my iphone (portrait, landscape is fine) the offset is about 15px too big because of thet settings in the media query, how can I resolve that by JS? I dont want the header to be too big on mobile portait orientation…in css that would mean I have to give the body -15px top-margin…? There might be a JS solution that I don’t know of?
Thanks, bye, Mary
$(document).ready(function(){
//first you difine 1 blank div and ad black class .up and down side ad class .top[Back to top]
$(“.top”).click(function(){
$(‘html, body’).animate({scrollTop: $(‘.up’).offset().top -100 }, 3000);
});});
He Guys,
So now I have a little problem with the script. When I add a simple a href link than will it work. But when I use a image map than I have no scrolling effect. Has anyone a Idea to fix this issue?
Thanks for the Help :-)
Did you ever solve the image map problem? I have the same problem…
I am getting this in the console:
Uncaught SyntaxError: Unexpected token ,
What now?
I like to know which setting defines target. When I have tested this code it seems it goes to bottom side of target not as demo. How to solve this?
hi, it works and looks great, but i have carousel in my page and those also use the # tag to work.. and this code generally applies on all hrefs having #.. so can anyone plz tell me how make it specific? this is my menu code and i only want it to be applied on this:
home
about
features
lists
forms
services
portfolio
testimonial
contact
oops, my menu structure is like this: nav -> ul -> li -> a
Just adjust the selector to:
:)
Thank you, Chris! I don’t sling JS, but I was able to just drop this in. Really appreciate all the help I’ve found on here over the years!
but it called twice bcause its contain HTML, BODY
you can test it.
Thank, it works well. But i was using fancybox. After i put these codes, it’s not working. I think it’s because of this “href*=#” but i really don’t know what i have to do. Can you help me?
Ran into the same problem when trying to refactor someone elses code. Not sure what is causing this issue.
Hi All,
I’m having a problem with scrolling and the scroll spy of bootstrap. So when I scroll, the menu item state changes accordingly to active which is what I want.. but i want the scroll to stop 60 before the anchor so i did top-60 but now the scroll spy doesn’t work properly, when it scrolls, it activates the previous menu item, how would i change that to -60 as well?? plz anyone’s help is appreciated..
ok, i found this solution and it solved the problem:
now another problem is that when i click the carousel next/prev buttons, While going to the next/prev slide, the page also scrolls around 30px or 40px up.. i deleted this offset code, but it had nothing to do with that.. anyone facing this type of problem?
Thanks a lot for the code. It works well on my website. To avoid the uncaught syntax error, the code for WordPress is:
I’ve been using this for a while and it seems to work fine. However, I have always looked at the results on Safari or Firefox on a Mac. The other day I opened up one of these scrolling page projects in IE (on a PC) and it did not work at all. Clicking on the page links simply opened to those page sections like a standard link. Yes, I know many will want to say “works perfectly for me” but does anyone have an idea why this might be so? Thanks.
OMFG!!!
Thanks to Devin Sturgeon!!!
It worked just fine.
Thanks for the article; a great find. Very simple implementation.
Here are the results on my website: leejohnson.it
Works like a charm. Thanks!
Awesome tip, saved me some time :-).
What if I want to click on one of the sub-items in the menu and be redirected to another page and scroll smoothly to a specific div? How can the code be modified?
Awesome scripts. How would I combine this and the horizontal scrolling one? :)
Thanks Chris! Adding here an improvement suggestion.
If you add this line just above the
return false;
bits…history.pushState({}, "", this.href);
That will add the anchor to the url allowing users to share the links to those anchors. <3 <3 <3
Thank you for sharing this line of code! I agree with the ability to share the link. Thanks!
THANK YOU for adding this! I couldn’t get it to work in WordPress without adding this line! <3
Thanks from me as well Vero! This is a pretty important step to have included from an SEO point of view.
Thanks for sharing!!
Hiya. In light of the one page site style in vogue today… Multiple tops of sections really need to be linked to. So this method seems to be working. But in light of HTML 5 how do i make a **** work. It seems this is only for smething wrapped in a a.href.
My code for examle:
Meet the Team
In your body tag
Or on your div on top…. write…
Then On your list nav link at bottom…
Return top
It works in Chrome, IE, FireFox and safari
Hi,
I have a scenario problem like this: I want scroll spy to only work for a menu item portfolio for example. after the portfolio area is finished, I wanted as active item. Then i have another area which is not related to portfolio and also not in my menu, so here none of the menu items should be active. then i have the contact area, where the contact item is active in the menu.
So the problem is that, after the portfolio item is active, it stays active, for the unrelated area until i scroll to the contacts area. then the active item changes.
I know its confusing.. but please help me out if you know the solution. I want the active state of the menu item to be activated for a specific height or area..
as an example, in this template: after you scroll to the ‘work’ area. it’s selected and after wards for the testimonial and then for the pricing table, it’s not selected, then again for the contact, the menu item is selected.
http://wunderkind.originthemes.info/demo/home-3.html
Thanks,
This is a fantastic script! I’ve used it a bunch of times already BUT I would like to know if you can use this script replacing the href=”#anchor” with something like onclick=”window.location.href=’#anchor’;” ??? I’ve fiddled around with your script a bit and have done a little research but can’t figure it out!
You
return false;
from the handler shouldn’t you juste.preventDefault();
to keep propagation.Spot on thanks for that.
I had some issues with this at first when using it to navigate a wordpress archive page. I noticed however that as I was using the_title(); in my links and targets that a date link like 1980’s wouldnt work when the slug of the post was 1980s. Silly mistake but works across all browsers well.
Thank you so much for this! I had been looking for this for a while and I couldn’t find anything nearly as good as this. I just copy/pasted this into my HTML file and changed the scroll speed, and it worked!
this is your friend from ASIA,
& i am in love with your code
thanks alot buddy ;)
It works well after the first click. I cannot get it work for the first click though. On the first click, my page does not scroll smoothly. It just jumps to the section. After that, it works fine. Any ideas why this might be happening?
Works well but impedes my other previously working jQuery functions from working correctly. Said functions added and removed classes. no longer works after using this script.
For one reason or another this script is borking my nested comments. I am using the html5blank wordpress theme. Not sure how to fix this. Any thoughts ? Because I am stumped
woooooooooooooo!!!!!!!!!!!!
After Thousands of times trying…….it realy worked…….thank you a looooooot!!!!!
Is there a way to keep the hash links in the address bar and to enable it to scroll smoothly back up to the top using just a ‘#’?
Did you already got answer? I have a very nive solution that I use on every website with a scroll to top button in the footer that apears after a certain scroll…just let me know,
bye, Mary
Chris, your script did the trick. It really works! Thanks a lot.
Thanks for the nice and simple code. I tweaked it a little bit to retain the hash in the URL.
After animation is complete, added back the hash to the URL.
jQuery('a[href*=#]:not([href=#])').on('click', function () {
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').stop().animate({
scrollTop: target.offset().top
}, 1000, undefined, function () {
location.hash = target.selector.substr(1);
});
return false;
}
}
});
Hey. I’m having a little trouble with my website. I have a main navigation menu and the different sections have a sub-menu. This code works perfectly when I use just the main navigation links. However, after using the sub-menu, which have a default function, on clicking the main navigation link, the prevent default doesn’t work and my page navigates to the section using the default behavior.
Any idea why this could be happening?
I think
('[name="' + this.hash.slice(1) + '"]')
with double quotes is better than just('[name=' + this.hash.slice(1) + ']')
because if you have a name with spaces (e. g. “Map of New York”) it doesn’t crash.Worked perfectly when I plugged it in, and exactly what I needed. Thank you so much!
Hey,
This is great for my menu; however, the animated scroll interferes with the JQuery UI Tabs that I have at the bottom of the page. The interference only occurs when there content below the JQuery UI Tabs pushes the page down further, so I left some empty space there for now in case you want to review. How would I excluded the JQuery UI Tabs anchor tags from scrolling?
I fixed it! Thanks.
I use this one, for single navigations
$("nav").on('click','a',function (event) {
event.preventDefault();
var elAttr = $(this).attr('href');
$('body,html').animate({
scrollTop: $(elAttr).offset().top
},700);
});
It worked.thanks!
Really nice help me ..Thanks in advance
For all those trying to get this work with Boostrap + Carousel Controls, just modify the first line for this one:
Thanks for this! Using JQuery tabs and this fixed my issue. :)
Thank you! This was totally the solution I needed.
Thank you! Quick and easy implementation that worked immediately – and saved me a bunch of effort.
Code works great but looking at the demo the “CSS Header” area the #top links don’t quite scroll to this area. What part of the code do I need to tweak in order to achieve that?
Hi ,
I like the script thanks it easier to understand and working very quickly
Thanks
Hi!
This lil’ snippet works really fine!
Just one problem though: when I click my in-page link and it makes me scroll to the desired place in the page and then try to scroll manually, manually scrolling doesn’t work until I’ve “caught up” with where I am on the page.
Can anybody help please?
Tweaked the code to support anchor ids with points.
Nice!
comment form should be before comments ha!..
Hy guys , i was wondering is there any way to make this plugin work in reverse order.
When i use it for the first time it works but when i get to the named anchor that i clicked first in my nav bar and try to smooth scrool upwards or more downwards its not smooth scrolling any more .
Ty in advance . Great plugin . All the best !
Thank you very much, it’s working great :)
Hi,
I was wondering if there is a way to get this to work for anchors on different pages?
Was reading through the comments but was unable to find a solution.
example.:
<a href="faq.php#new" rel="nofollow">new FAQ</a>
should open the page and smooth scroll to the anchor.On the same page, the script works like a charm.
Hi..Nice work.. Can you please tell me how to load the same div using mouse scrolling.
This might be what you are looking for. This site provides a template, parallax website with “SMOOTH” scrolling effect for download.
http://iiiji.com/developing-parallax-smooth-scrolling-website/
The 1st time a click my link, it NEVER scrolls smoothly. It works perfectly, however, every other time (the 2nd, 3rd, 4th, 900th,…). I’m guessing it’s an issue with the order things are loaded? Any help would be much appreciated.
Disregard my last comment, there was nothing wrong with the code. The problem was caused by my browser settings…
Chris, thanks for this great script. But it isn’t working on my mobile devices. How can I fix this? Our site is responsive but when I change the windows size to less then 600x width than the script is not working anymore. Anyone any idea how to fix this? Thanks already!
http://elearning.theleansixsigmacompany.com/my-training/directions/
Thank you so much for your help! this works so perfectly well :))
Greatly appreciate your help in solving design issues.
For anyone who wants to activate the nav tabs as the users scrolls:
I just added a function that activates nav tabs as you scroll & here is the link with the code that helped me.
http://codetheory.in/change-active-state-links-sticky-navigation-scroll/
Brilliant!!! Thanks!!!
i used this on my site but its not working … can anyone let me know why ??
For those using bootstrap and want to stop the interference with other jquery anchors such as tabs here is a quick fix.
Change this line:
To this:
Then add class page-scroll to your a href tags.
This will only animate a href with the class page-scroll
I have put (with help) an auto scroll function in a widget in the side bar. I would like to add it individually for some posts that need a different scroll speed. I cannot for the life of me figure it out. All of these scrolling codes on here and I don’t know where to even put the code. In css editor, in the post itself? Obviously, I do not know much about code.
I figured it out with a widget short code thing and it’s working good. It’s a plug-in called Widgetize Pages Light.
The code works great and was very easy to implement! I do need help. Depending on which menu items was selected, after the scroll, the user’s cursor may end up on top of image that has a mouseover event. If that happens, the mouseover is executed and is really annoying. Is there a way to move the cursor to the left margin so that the cursor does not end up on a mouseover image?
Not working if html,body has overflow:hidden
I use HTML5 and see that the code work if you put it in the <body> before bookmark, so:
Has anyone had problems with using the
:target
CSS selector and this code? It seemed to ignore my selectors (trying to trigger an animation) and everything worked without the script.Hi Mark,
Currently implementing this code with
:target
CSS selectors, and realizing it breaks the animated behavior for showing hidden divs. Did you find a solution?
Thanks!
Nevermind! Found out from a few comments around. Just add:
in the final if statement.
You helped me alot, thank you very much :) :)
This code is not working in Internet Explorer 8 and above version . . . Plz help……
Thanks. You are perfect!!!
Great example, Chris! I made (a few) modifications and created a custom Angular directive for beautiful, smooth scrolling. Thanks!
Is there a way to modify the script, so that it automatically scrolls to the first anchor id after the page is fully loaded?
To answer all the people who having conflictions, like Bootstrap Tabs aren’t working anymore or it breaks another slider/scroller. The solution:
Use rel to active a smooth scrolling, by setting the rel = …
Example:
<a href="#contact" rel="nofollow">
nofollow? should be scrolling ofc.And change the code from:
$('a[href*=#]:not([href=#])').click(function() {
TO:
$("a[rel^='scrolling']").click(function() {
Good luck!
Melroy
I just came across this issue and was racking my brain on what to do. But this worked great. Thanks Melroy.
Hi! I followed the instructions but yet to get it work. No idea what is going wrong.
Hi Davin,
How can I make it work only with the menu bar links. The present code is disturbing by tabbed panels which has # link.
how to add class in every id section
Hi everybody. Thanks for giving your ideas and code. I am trying to make this work on my page, but I cannot figure out how to make the scrolling stop like 160px under where it stops now in the example. Like I have a header that I want always to show and the smooth scrolling should stop just below that header. Tried via css #page-wrap, also on the different #anchors-id, but none of it worked. It always scrolls all the way up. Any idea there? Thank you so much in advance.
Hi, I tried again… found something. So after further googeling into that topic I am thinking it got to be something within the javascript. Thing is, I am ok with HTML, ok with CSS, ok with php (or at most times…) but not a javascript geek.
How do I get this right?
…
{scrollTop: targetOffset – 100}
…
would this be correct?
…
$(function() {
$(‘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-160
}, 1000);
return false;
}
}
});
});
…
I styled my menu as fixed position dots Is there a quick way to add active class with a different style so that whenever user is scrolling above the section right dot is changing look?
Its missing ‘=’.
Should be ‘===’ instead of ‘==’.
I’ve pasted the code below.
/* Smooth scrolling */
Holy moly, so simple, so clean! Thanks so much!
Hi. I’m new to web develpment so I’m just trying to fully understand your code. Prior to reading this post I had coded a smooth scroll as:
And to animate a scroll to a specific element:
I’m trying to understand why you have code like:
if (location.pathname.replace(/^\//,”) == this.pathname.replace(/^\//,”) && location.hostname == this.hostname) {
var target = $(this.hash);
……..
Whats the purpose of those lines of code?
it worked perfectly on my website!! amazing!
however could anyone explain exactly how it does work
You are amazing, Chris! Thanks for this snippet of awesome; it really helped me out with a task I had to take care of today!
It works brilliant! Thanks a lot.
Hi guys. My site is lovatotribe.com and the script won’t work :/ What is wrong with it?
try with document ready, script is loading before other elements and possibly colliding with the rest of js
what is document ready? im not really into js and scripts
http://learn.jquery.com/using-jquery-core/document-ready/ but if you not good with js i would recommend to pay somebody 10 dollars or so to do it, there might be million reasons with WordPress
This is the only thing on my website that needs jQuery, and so I’m trying to find a pure JS solution so I can stop using jQuery for my site, but I haven’t been able to find anything that’s anywhere near as smooth as the jQuery solution. What is it about jQuery that makes it scroll so much smoother, and does anyone know of a good JS solution?
Great, it works. I love you. haha
This script is awesome.
Wow worked great for me! I’m currently working on replicating of the amazing sidebar on the Bootstrap site (http://getbootstrap.com/components/) and this is a super helpful step. Thanks!
Can the same be done if hash url is used?
eg. “css-tricks.com/examples/SmoothPageScroll/#two”
I have a page with a table of contents and was looking for a solution to the problem of anchor links showing up in the history (user hitting back doesn’t actually take them “back” just back through their journey in the page).
After two hours of messing around with javascript window.location and scrollTo I found this simple and perfect code so thank you, Thank You, THANK YOU.
If anyone is having problems with a fixed menu by having it scrolling to a section and then scrolling back when you click the same link again, just change target.offset().top to document.querySelector(this.hash).offsetTop.
Will look like this.
Did you use
overflow: hidden
anywhere in your CSS? Even when overflow-x is used it can cause the scroll to not do anything at all. It worked for me to remove it!Chris, ff I can make a suggestion for accessibility’s sake, it’s worth amending this to incorporate focus for the keyboard, and update the URL.
reference:
http://www.sitepoint.com/learning-to-focus/#the-result
For those having problems with elements being highlighted after scrolling, just add the following just before return false:
document.selection.empty();
return false;
I have a website where changed the divs size. When such reposition the divs, receive a new position. When such not working this smoothing scroll script. Please, help me. Thank you very much.
Thank you so much, it works great!
SquirFly, thanks a lot!
I have added this to my weebly built site. (i am a rookie). It works. The issue I am having is that it jumps to the section. I can’t get it to scroll. there is an animation query loaded for easing. the web page is http://www.jrs-spiceco.com
Free spices for anyone that can help me solve this.
Once i went to the site in safari, the scroll down works now works in chrome as well. It doesn’t scroll back to the top slowly though.
Had to reload due to trying to add sticky content. Now can’t get the scroll do anything but jump.
Hello
When I change “return false” to “return true” my site flash every time when I click on a menu.
Is there any solution?
In case anyone has this issue. Using this code site wide on a bootstrap based site caused bootstrap accordions to stop working (anything which uses # in the href basically). Anyway my solution was to add this:
To line 2 of the snippet.
#accord being the start of the # I was using to trigger each accordion like:
It’s WordPress so
outputs #accord2126 (or whatever the post id is)
The new line in the smooth scroll then ignores any # starting with #accord and now my accordions work :)
Of course if you start any other # with #accord they will be excluded too
Thank you very much Vanv for this trick. I was looking for this and it saved my time. It is working with now all bootstrap things which were having conflict.
Thanks again! :)
hi
the script works nicely,
however when I click a link to an h2 tag, it jumps after the h2. not exactly to the h2 it supposed to be.
Any thoughts/suggestions for getting this to fire after a collapse is ‘shown’?
Using Bootstrap 3, so the shown.bs.collapse event should be available, just unsure the simplest way to do so.
Thanks for sharing this! And another thanks to vanv who pointed me in the right direction to not break my site (I would have completely missed the bad interaction with accordions). Excellent post! :)
Great! Thanks you! jQuery.scrollTo not working with the mobile menu, but your script is running.
Thanks! It was very helpful for me :)
Hi,
does anyone have an issue with Bootstrap drop-down toggle?
My menu doesn’t close after clicking a link.
Put the code above in a code above tag.
The HTML: Whatever text you want
#contact is my anchor tag, and you should change it according to where you want it to jump on the site.
Hi Chris,
You might want to add a note that you can not use the code posted here IF you are concerned with accessibility. This hijacks the normal browser behavior and does not set the focus (even when you set tabindex=”-1″) on the div with the anchor. The reference URL has a few versions that can be implemented accessibly.
Thanks! :)
Hi there, I tried this tutorial to work on my website which also includes diagonal scroll (I added ‘scrollLeft:target.offset().left’ in js). It works perfect until I add ‘overflow:hidden’ in my css. It was answered earlier with ‘$.noConflict();’ but it somehow does not work for my code. Can somebody please help me with making the code work with ‘overflow:hidden;’ in my css? Thank you.
Hi again,
I changed a few things in my code and it worked like a charm. I am no longer using ‘$.noConflict();’. I changed all ‘$’ to ‘jQuery’ and changed the ‘overflow’ property to ‘hidden’ in my css for body{}. And the code works just the way i wanted it to. Thanks heaps, your code saved my project!
Also, for those who want a scroll in a particular section of your website, just add a height and ‘overflow:auto;’ in the css for that section.
And yup, I worked on Devin’s code.
Cheers Chris and Devin.
This doesn’t seem to be working when the anchor link has “.” character in it. I tried to incorporate it to my web template, and the subsection links in the table of contents (created by pyHat) have “.” for which this script isn’t working. It works for the rest of the links. Any suggestion would be appreciated.
Never used codepen it’s awesome… anyway…
I made an example for you to use…
I’m brazilian so if anything i said is wrong just ignore it haha’
http://codepen.io/anon/pen/avdeqx
(didnt read through all comments, so i dont know if anyone already said it)
Many users will hate you for replacing standard html behaviour with this javascript. There should be a big disclaimer in this article. Things like this should not be done. This is basic functionality, dont change it.
When two links with the same “href anchor tag” are on the page, the page scrolls up to the top and back down the anchor tag, instead of just staying at the anchor tag.
Any ideas how to keep them at the same #anchor tag?
http://testing.apliiq.com/custom/pocket-tees/crew-neck-pocket-tees
Hi, how can i put it in my website. im a rookie so i dont know what to do, and im really confused -_-
Thanks for the code, works wunderfull.
Is it possible to exclude a class from the scrolling? Thanks
I’ve made a plugin for this that leverages Popmotion instead of jQuery:
https://github.com/Popmotion/scroll-to
Hello Chris,
I’ve use this code and it works perfectly. but I noticed it wont work to a new version of jQuery. Do you have a new updated code to work on the new version of jquery?
Hey everyone, I was having an issue with the page skipping if I attempt to scroll while the jQuery is animating. I added a small snippet of code to this to cancel the animation on user interference (mouse scroll, up or down arrows etc)
Instead of “Top” I’m using a font awesome chevron, how could I incorporate into the original code a fade in/out aspect at a certain page point for that icon?
Thanks
To the author, you are god. I am a learner and this just made my day! Please keep up the good work.
Hey it’s very nice. thank you!
Hello,
I have a fixed header and would it to scroll to the bottom of the header, this is addressed by Frank’s reply above but I do not understand how to combine the codes.
Thank you for any help.
Spoke too soon, I figured it out.
Hey,
I was trying to make this work with a select dropdown menu, but I haven’t been able to get it to work. Any idea how to get it to work?
Comment of SquirFly is working.
Thanks alott !
works perfect, thanks!
$ and animate are not js native functions, this example does not work !
if you are using WordPress or new jQuery version just change all $ sign on the code snippet to say ‘jQuery’ instead and should work can use WP version of jQuery and don’t need to embed old version to support $ symbol
I am hoping to employ both smooth scrolling and :target trickery, but the smooth scroll technique strips out the #anchor from the URL so that the :target does not trigger. Any ideas on how to fix?
http://emdac.org/chest-pain.html
The reference links are what I am trying to get to work properly.
Usefull!
Thank you so much! Your instructions worked like a charm.
Hello
the various evolutions of the script are working fine (at least as final effect) what I kindly ask is, when I click the link that takes back to top, in the address bar , the homepage url gets added with the #namelink
Is there a solution to avoid this ? Or it should not appear?
Thank you
Robert
If you have a static navbar, your anchor text will probably be covered by it. I modified by subtracting 70 from the scrolltop:
I also changed the 1000 to 500 to speed up the animation a bit (half a second versus a full second).
bootstrap giving accordion error please help :(
Perfect.. working nicely.
Thank you
Hey, just noticed this doesn’t work with jquery 1.12.0 (which is what latest html5 boilerplate uses).
Works fine with 1.11.0. Just thought I’d let you know!
Cheers.
@Devin Sturgeon :- Thanks for the code, worked well for me!
Here’s a slightly nicer version of the clip
Thanks bro, it works.
Thanks so much! Works great
Hey, I was wondering whether a value could be subtracted from ‘target’ to end the scroll before it’s meant to end. For example:
target = target – 80;
to end the scroll 80px sooner. I’ve been trying to figure this out for a while but have had no success, any ideas?
Thank you so much :)
Thank you for sharing, it works great.
Just as a heads up! if anyone is getting a JS error
Uncaught Error: Syntax error, unrecognized expression: a[href*=#]:not([href=#])
I changed
a[href*=#]:not([href=#]
to
'a[href*=\\#]:not([href=\\#])'
It showed up in a WordPress Site I maintain with update 4.5
You just saved my life man. After updating to 4.5, half of my scripts weren’t working. I narrowed the problem down to this one, did a search, and BAM – you had the answer. Thanks so much!
Better: use quotes
a[href*=”#”]:not([href=”#”])
https://github.com/jquery/jquery/issues/2824
https://www.w3.org/TR/css3-selectors/#attribute-selectors
THANK YOU!!!!!
It only works when i have to scroll down but it doesnt work when i have to move up?
$(function() {
$(‘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;
}
}
});
});
If you’re utilizing WordPress and upgrade to version 4.5 make sure you are escaping the special characters on the first line to prevent errors. Quick write up on it here: https://www.wpcover.com/upgraded-wordpress-4-5-syntax-error-unrecognized-expression/
Spent ages trying to find a jquery solution for this that actually worked in Internet explorer and didn’t simply jump to the #
Many thanks!
YO THIS WORKED THE FIRST SECOND I TRIED IT
For some reason, this stopped working on my site with the WordPress 4.5.2 update.
All my other scripts in the same JS file continued to work.
Thanks a lot!
Nice
I really don’t understand the utility to do a tutorial just for people who already know to use Javascript. I don’t know how to use Javascript and this tutorial doesn’t say anything to me, consequence? It is pointless. I take you code, I paste it between inside but it doesn’t work because, evidently, you take for granted something.
I do not understand the utility to criticize in this way the shared code (as in the code may change), for free. I do not see where it says “tutorial”, where it says “with this you learn to use javascript.” It’s a snippet, not a tutorial. And it does not start from the idea that it is easy for everyone (despite the fact that this one is, simple). And again, free sharing of the author, so maybe more respect and RTFM. You get angry because your “copy-paste” without effort, probably on a ready WordPress theme or similar, it does not work? Really? Cmon! :)
No utility – just frustration. Thanks guys @css-tricks.com for the great work you do for us! Luckily there are not so many people like elena disrespecting the work you do (like Diego said, for free).
@elena if you don’t know javascript, then go study or take some online lessons. Once you know the basics, you will understand how to hack this script. This is a SNIPPET and not a TUTORIAL. Be respectful to the work the others do for the community.
Is it possible to do this when your website is horizontal scrolling enabled? Doesn’t seem to work, it only works when website is vertical scrolling
I use this script (Thanks Chris!).
I didn’t see anyone else post this so here goes.
We’ll need to escape the "#"s to avoid any errors. Update the query to this:
$("a[href*=\\#]:not([href=\\#])").click(function() {…
preety good worked for me
Hi Chris,
it’s working perfect for my webpage thanks for sharing the code..
Hello,
i have one question:
I have a fixed header on my website.
Now the scroll should stop 100px before the anchor. Is this possible?
Thanks.
best regards.
Bernd M.
Just add a pixel value to the end of the scrollTop line.
e.g. scrollTop: target.offset().top – 100
Thank you, Callum!
It is working.
I’ve been trying to get it to work with horizontal scroll with no luck. Any suggestions
It worked like a charm! thanks a lot!
I’m a complete newb. Thank you for the code. Works great!
But I am having a conflict in conjunction with jQuery Popup Overlay. The scroll function disables the Popup. I think it may be that they both have functions that are not named. I’m confused about naming functions.
How would I name your function and then execute it?
Hi There! Excellent code.
Can someone help in sorting out how to use this snippet with BS Carousel. It also uses hashes and every time I try to press Left or Right button on the carousel it just slides a bit up to where the div starts.
anyone can advise anything?
Newby my self ;)
Can anyone give pure CSS solution for this?
Thanks Chris. Here’s my contribution – dynamically speeding up the scroll time depending on the distance scrolled, taking the target element’s distance from top. Change max and min scroll time as necessary.
Brilliant snippet!
@mrhorse, I’ve used your version. At first, I thought it wasn’t working the other way round (smooth scrolling back up the page); then I changed the value of baseMinScrollTime to the same value as baseMaxScrollTime and… voila!
‘My Example‘
Gonna try and incorporate into a project that laden with Bootstrap components… so I’ll be testing out the various suggestions, posted in this thread, for such situations.
Many thanks again, @mrhorse… and thanks to you too, @Chris.
Ess
Ok… so it doesn’t work in a Joomla! project I’m working on. Tried putting it before , before , in th ecustom javascript section… nothing.
Any help with this would be very much appreciated.
Ess
Thanks Chris, works great!
Best regards
Ronald
So this jquery snippet has always been with me. I love smooth scrolling. Although just put the snippet into my init.js script that executes on document ready.
In a website im doing i have the materialized css/js implemented, and the jquery function that closes my menu on menu item click, this all is inside the jquery in my scripts. However the moment I add this snippet to my init scripts it makes my menu stay open even after my menu item is clicked. been looking for errors in firebug with no luck I know its because there is something in the jquery snippet thats causing it just dont know what it could be any suggestions?
Thanks to Chris Coyier & Devin Sturgeon,
It’s working fine, no need to add and remove anything in code.
Thanks for this. Was working well until recently. Now, on the first click, it scrolls down to about 700px above the section it should be scrolling to. Any subsequent clicks scroll to the correct position, it’s just the first click that’s being weird.
Using jQuery 3.1.0 and WordPress 4.6.1
Thanks Charlotte : ) However, I’ve had to use compatibility mode to get it working in WP – replacing all the “$” signs with “jQuery” .. Using WordPress 4.6.1–en_GB .. strange .. but I have no idea what I’m doing ; )
This really works for me. Thanks Boss
Fantastic work. Thanks for sharing!
Although a reference for the code is given for jQuery, could anyone tell how should i put it using java script (window.scrollBy)…
Apparently, applying onclick to a function which contains (window.scrollBy) doesn’t seem to do the work… any suggestions?
I realised there is a problem with the code provided, because it specifically didn’t work for me. Specifically the first line of code
$(‘a[href*=”#”]:not([href=”#”])’).click(function()
Now, this selector is not valid. # is a special char and needs to be escaped like a[href*=#]:not([href=#])
see https://api.jquery.com/category/selectors/
Hope it helps someone somewhere
Sorry, actually it’s supposed to be like a[href*=\#]:not([href=\#]) with those \ before the #
If the # was unquoted, yes, it would need to be escaped with a /, but in the code provided here, it is quoted and so doesn’t need to be. Check out the working demo at the bottom of the page.
Thank you friend :)
How do i make this work on a button click, this only works on an anchor tag
Is there any code here that doesn’t break anchor url functionality?
The code in the post doesn’t add a #location to the end of the URL, and the ones that do don’t support back/forward.
They’re all broken.
Hi Chris,
If the page with lazyload(images), the scroll is in the wrong position
Then the code for lazyload is wrong, you should add image height and width in the img tag attributes so it already takes the appropriate space.
The code worked like a charm. I just copied the code and made no modifications and it worked perfectly.
But why isn’t there any pagination for the comments in this website!! I had to come to the bottom of this page to make this comment.
It would be nice if the ‘leave a comment’ section would be at top or else there’s some pagination
I am using shopify – debut theme. i would like to have a smooth scroll to a few section in the home page. Have did the necessary anchor point, currently the menu button would jump into individual section instead of smooth scroll.
Inserted the following code into theme.liquid but its not working for me.
thanks i use your smooth effect its so easy .
Hi,
This code works amazingly well! However the only problem I’m having with it is that its preventing my Bootstrap modal from working at all for some reason.
Any ideas why / how to get around this?
Thanks,
Alex
Ok… further to my comment on 30/10/16, I’m happy to say I got it working in my Joomla! project. I just needed to enclose the script in $(document).ready(function() {code here}).
Once again, many thanks for making my coding life a little easier.
Ess
Well although this looked like a simple solution, it will conflict with your frameworks such as Bootstrap, that use any #anchors.
It will also by why you get issues with menus, modals and other scripts that use and anchor.
So for example, the BS tabs will not work with this code.
Pity, but not usable for me.
The script works great, but only when I remove the defer attribute from my script tag. The async attribute also causes the script to stop working. Is there anyway to get this working with either of these attributes in place?
I believe the correct version is:
$(document).scrollTop($(document).scrollTop() + $(‘a[name=”target”]’).offset().top)
It also works on mobile!
Hi Chris,
I ‘ve noticed a problem with the code. it works fine when you click on navs for just once but problem is when you click multiple time. for example – there are 5 nav links (fixed position to top) now suppose you click 10 times on 3rd link and quickly click on 5th then 2nd or any other links in row then page doesn’t scroll or responds quickly as soon as you click on other navs after clicking the first clicked nav. It waits for some time after multiple clicks on first clicked nav, like as if it is still counting those multiple clicks and then it counts those clicks on other navs. your whole page starts animating back and forth depending on your clicks and targets on page.
please give solution to the problem.
i hope i am clear, if not then feel free to ask.
thanks
How would any of the above scrolling solutions mentioned here work with additional events? For example, lets say onClick() I wanted to a.) scroll to some position on the page smoothly, and b.) hide other elements? Gone are the days of simply setting up page anchors and simply clicking a link to scroll smoothly to location using straightforward HTML. Like fiber, this makes me sad.
The other thing I’ve noticed about this approach, is after you click the link, the anchor remains in the “active” state…Hmmm
Man, this is great! Brilliant work!
Quick question for anyone that can help.
I’ve been changing the animate time and having no luck in slowing down the scroll…sorry I haven’t had time to dive into this further on my own, but was hoping someone knows the fix for this?
One of the easiest ways from CSS – attach overflow attribute to body element, then put scroll-behavior to smooth. Works fine in FF :)
Hi, I know this is a very old post but can you explain how to execute this if I have the href like
<a href="/#anchor">Anchor Text</a>
because when I have the same without the forward slash, it just works fine<a href="#anchor">Anchor Text</a>
. See the disparity here. I will really appreciate if there is an easy fix for this.https://jsfiddle.net/ayanize/vu5bxh85/3/ – does not work
https://jsfiddle.net/ayanize/sc92tL8L/23/ – works
Thanks for the nice article by the way.
As far as I know,
<a href="/#anchor" rel="nofollow">
isn’t correct HTML.<a href="#anchor" rel="nofollow">
– Correct<a href="/link_to_another_page" rel="nofollow">
– Correct<a href="/#anchor" rel="nofollow">
– IncorrectHi,
I used the code on my page and it worked right out of the box. But I have one question: When I click on a link, the script automatically selects the section which it is linked to. I don’t like that, is there a way to prevent the selection?
Thanks a lot.
Hi, noticed the same issue. If you comment out/remove the following lines it removes the focus. I don’t know how this affects the rest of the functionality though, but it seems to work for me at least :)
Works perfectly for in page links.
What about URLs? I can’t get it to work on links to other page:
e.g. /new-page.php#bottom
Is this possible?
Add this before return false; to update browser url.
window.location.hash = this.hash;
Is it possible to smooth scroll to anchor links that are within a div with overflow-x hidden? I want to make a slider, where clicking on a button scrolls to the next anchor link. However, the smooth scroll happens on the window scroll bar, not the scroll bar on the overflow hidden div.
In the latest version of Chrome, the Smooth Scroll with jQuery version of the code above causes a thick, blue border to appear around the item that is the anchor source of a hash link.
So if I click on a link with a hash mark, it jumps me down to that section fine, but then places a blue border around it. This happens only in Chrome. The other browsers don’t see to do this.
Any ideas why? I don’t want to hide globally the ::focus outline but that’s the only way I can see to get around it and still have the code work.
Yes, it’s the focus() function. Just still with css the
element::focus{
something for the outline
}
…or remove the code that does the focus.
Tina, remove only this line: “$target.attr(‘tabindex’,’-1′);” ;)
I added this to my page, and yes, it now smoothly scrolls to given anchor position within the same page.
But this is not what I need.
I’d like it to open up the link first (so it goes to the page with the article on it) and then it needs to scroll down to that specific article. Right now it just scrolls to the anchor-position and it doesnt seem to care about eveything in front of the anchor hash. I use #g-mainbar as anchor (gantry5 / joomla)
Example of my nav-menu links:
1 -“http://www.xxx.nl/development/diensten/dienst1#g-mainbar”
2 -“http://www.xxx.nl/development/diensten/dienst2#g-mainbar”
3 -“http://www.xxx.nl/development/diensten/dienst3#g-mainbar”
So when i’m on the home page and I want to read information about “dienst2” I press menu button 2, It should load that page, and then it needs to scroll down to that article. I need this kind of behaviour because there is a full-screen header image on top of every page. I want there to be a bit more animation as to where the user has actually navigated to.
Stefan, I need the same thing…did you ever figure this out?
A couple of things to smooth things out a bit…
1) Most sites have a navbar or something that needs to be offset. You can add an empty link as an anchor in your CSS, like so:
2) The provided code doesn’t reset the hash, so I added these lines via jQuery:
then…after the scroll, add this line…
try this
It sounds like in the newest version of Chrome there is a bug that causes the scroll to jump if you have an offset (for a fixed navbar). This appears to be an issue with focus, this block of code:
Does anybody have a workaround?
Thanks!
Same issue here, I got around it by creating a function which cancels any scrollTo on focus:
You can then use .focusNoScroll() in the place of .focus() to focus on to the element without scrolling to it.
In case it is helpful to anyone else, here is my full code which utilities the above, looks at the height of my fixed-nav header (which changes when scrolling and responsively) and offsets the scroll accordingly. To my knowledge it works as expected:
Thanks so much, can confirm this works for me!
Very useful script!
Since it felt a bit slow when scrolling short distances, I added a kind of arbitrarily-calculated formula to decrease scroll-time relative to distance.
How to add smooth scroll effect on table of content (TOC) when clicked?
Hi. It works perfectly but a question: is it possible to set active menu item on click or on page scroll?
This code works on Shopify.
Keep in mind, that for Shopify, for some reason you need to add custom scripts right before the closing tag.
I’ve use this code in a french website.
The id were auto-generated and I had special characters in it.
I replaced this line:
with this one:
And now it works like a charm.
Great Job!
I just was trying to add an extra option to make reached section be blinking (or showing any other kind of effect), using css animations and the pseudoclass :target.
But I can’t make it work, perhaps because :target can’t work with this script since the url anchor is hidden from the browser by the script itself, so the browser can’t relate the url to the target… am I wrong?
Has anyone a solution (or can someone suggest a way to take) for that? Not necessairly through css. The best way would be (I think) by adding something within the script (like a function applied to a css class) and afterwards assigning that class to the element we want to be blinking.
Great, simple to follow tutorial. One question, does anyone know how to prevent the browser from highlighting the div/element that’s being scrolled to?
You can also make with css
html
{
scroll-behavior: smooth;
}
WOwow! GREAT! Thanks buddies!
Re: CSS’ smooth-scrolling behaviour… please don’t, at least not yet.
I’ve been suffering for a month or so now on the occasional website that uses it. The scrolling works, and it’s smooth, but it adds 500-1000ms of tasty, tasty lag before the scrolling starts any time I use my mousewheel.
At first I thought it was some weird trend of having snap points all over the place, but discovered it was this CSS property when I tried using it myself yesterday.
Happens (for me, at least) on the current release of Chrome, both on Windows and Ubuntu.
From an a11y standpoint what are the thoughts on adding
$target.css('outline', 'none')
if the element was not normally focusable? If you are using normal anchor links no outline is added to a non-focusable element such as adiv
, so I feel like this would actually make the functionality closer to the default browser functionality. This is what the updated callback would look like:Of course if the element being scrolled to can normally be focused on we don’t want to remove the outline. If anybody has any reasons why you wouldn’t want to do this please let me know!
Thank you for the great article. I am just wondering if pure Javascript and CSS behavior functionality are not supported in Safari browser when you referred to the polyfill solution you said: “you’d probably only reach for this if you were doing something with scrolling the page that couldn’t be done with #target jump links and CSS.” I cannot seem to understand in what way was this functionality of smooth scrolling achievable in #target jump links and CSS. I am new in this field so I really appreciate any help :)
Nice post, thanks! What is
.not('[href="#0"]'
supposed to prevent? Is there some magical usage of #(int) that I’m not aware of?Hey JP! That’s a handy way to exclude any element with an href attribute of #0 (i.e.
Link
). In this case, that’s an anchor link (#0 will scroll the user to the element on the page withid="0"
) and the snippet is excluding any link that targets thats ID.The point is that ID’s can’t start with a number. Or basically shouldn’t. So if you use #0 on a link it’s a dead link, rather than just # alone which jumps you to the top of the page.
Okay – that is all great and so on…, but – there is a big problem and question. In what way we can update url by both clicking on menu items and scrolling to section id’s by hand? It updates only by clicking, not by scrolling, unfortunately. The main goal is to obtain new updated url and use it further, e.g. in multipage/multilingual environment. Does anybody have any idea how to implement it in this working script?
Sorry for the delay – have an answer for my own question.
Just remove “e.prevent.default()” in menuItems.click(function(e){} and add
“location.hash = ” + id” in $(document).scroll(function(){} just above you add/remove active class to menu items.
I created a quick gist for a Js only version: https://gist.github.com/hsnyc/6fca8b5c237ff80a650674680e0be082
I can use this code created by you for a project with a commercial purpose that you intend to do.
if you can thank you so much
if you can’t, thank you.
Yep, use anything you’d like:
hi, works great. It seems to conflict with bootstrap-carousel navigation.
The site I implemented on is not yet online.
Thank you! This really helped. Loved reading about accessibility scrolling. A better UX would be to provide an offset above the scrolled content so that it does not go all the way to the top of the screen.
I think this is great!
I do have a question though…
What is the purpose of the following line?
If the target does not have a length then it won’t have a hash…
does that make sense?
I don’t understand the purpose of the second line. You are already checking if the target has a length in the if statement just below that.
Before HTML5, there used to be an attribute called
name
for anchors. That line tries to usename
in case it cannot find a usable hash on theid
attribute. Thename
attribute is no longer supported. You can remove that code, if you want.I am getting an exception from JQuery when the link references an id rather than an anchor name because
[name=link]
doesn’t exist. IDs are anchors too.I’ve been using this code for a while. Recently, I noticed an issue on mobile Safari, where the page jumps to the scroll element at the end of the animation. This happens because I have set for the scroll to occur a set distance before the anchor point, and then IOS seems to auto scroll to the element when the focus() function is called. To solve this, I have added the {preventScroll: true} option, so focus({preventScroll: true}).
Oh yes, in regard to Parimal JS above- the offset doesn’t work for links from external website, and also for links within the website from different page to different page (with anchor)!
how to solve this problem?
I know this is an older post and not sure if you will see this or not, but if I’m using smooth scroll on a back to top button, is there any way to add a class to the button while it’s scrolling to the top and then remove the class once it reaches the top. For instance, I’m adding the ‘show’ class when it breaches the offset I have set, but I’m wondering if I can add an event listener for when you click the button it adds a class and when it reaches the top it removes that class. thanks.
Based on the inputs, it seems like the user is providing information about different techniques and tools for achieving smooth scrolling in web development. They mention native CSS features like scroll-behavior, a native JavaScript version of smooth scrolling, and mention an available polyfill by Dustan Kasten. The user also emphasizes the importance of considering accessibility when implementing smooth scrolling and suggests reading an article by Heather Migliorisi for code solutions.