How to scroll an HTML page to a given anchor

559,821

Solution 1

function scrollTo(hash) {
    location.hash = "#" + hash;
}

No jQuery required at all!

Solution 2

Way simpler:

var element_to_scroll_to = document.getElementById('anchorName2');
// Or:
var element_to_scroll_to = document.querySelectorAll('.my-element-class')[0];
// Or:
var element_to_scroll_to = $('.my-element-class')[0];
// Basically `element_to_scroll_to` just have to be a reference
// to any DOM element present on the page
// Then:
element_to_scroll_to.scrollIntoView();

Solution 3

You can use jQuery's .animate(), .offset() and scrollTop. Like

$(document.body).animate({
    'scrollTop':   $('#anchorName2').offset().top
}, 2000);

Example link: http://jsbin.com/unasi3/edit

If you don't want to animate, use .scrollTop() like:

$(document.body).scrollTop($('#anchorName2').offset().top);

Or JavaScript's native location.hash like:

location.hash = '#' + anchorid;

Solution 4

2018-2020 Pure JavaScript:

There is a very convenient way to scroll to the element:

el.scrollIntoView({
  behavior: 'smooth', // smooth scroll
  block: 'start' // the upper border of the element will be aligned at the top of the visible part of the window of the scrollable area.
})

But as far as I understand, it does not have such good support as the options below.

Enter image description here

Learn more about the method.


If it is necessary that the element is in the top:

const element = document.querySelector('#element')
const topPos = element.getBoundingClientRect().top + window.pageYOffset

window.scrollTo({
  top: topPos, // scroll so that the element is at the top of the view
  behavior: 'smooth' // smooth scroll
})

Demonstration example on CodePen


If you want the element to be in the center:

const element = document.querySelector('#element')
const rect = element.getBoundingClientRect() // get rects(width, height, top, etc)
const viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

window.scroll({
  top: rect.top + rect.height / 2 - viewHeight / 2,
  behavior: 'smooth' // smooth scroll
});

Demonstration example on CodePen


Support:

введите сюда описание изображения

They write that scroll is the same method as scrollTo, but support shows better in scrollTo.

More about the method.

Solution 5

Great solution by jAndy, but the smooth scroll seems to be having issues working in Firefox.

Writing it this way works in Firefox as well.

(function($) {
    $(document).ready(function() {
         $('html, body').animate({
           'scrollTop':   $('#anchorName2').offset().top
         }, 2000);
    });
})(jQuery);
Share:
559,821

Related videos on Youtube

Juha Syrjälä
Author by

Juha Syrjälä

GitHublinkedin

Updated on August 29, 2021

Comments

  • Juha Syrjälä
    Juha Syrjälä over 2 years

    I’d like to make the browser to scroll the page to a given anchor, just by using JavaScript.

    I have specified a name or id attribute in my HTML code:

     <a name="anchorName">..</a>
    

    or

     <h1 id="anchorName2">..</h1>
    

    I’d like to get the same effect as you’d get by navigating to http://server.com/path#anchorName. The page should be scrolled so that the anchor is near the top of the visible part of the page.

  • Juha Syrjälä
    Juha Syrjälä almost 14 years
    I tried this and decided to use this. You were also the first and had shortest code.
  • gnarf
    gnarf almost 14 years
    As far as creating a selector to find the <h1 id="anchorName"> or an <a name="anchorName">, use $('#'+hash+',a[name='+hash+']') or slightly optimized $(document.getElementById(hash) || 'a[name='+hash+']') which will search for the element by id first, and resort to searching the a's only if one isn't found.
  • CodeJoust
    CodeJoust over 11 years
    @gnarf - There isn't any need to optimize the '#' selectors in jQuery - they're already optimized for you. It's fairly easy to see if you've read the jQuery source code.
  • gnarf
    gnarf over 11 years
    @CodeJoust - I'm on the jQuery team, I've read it many times, and yes $("#selector") is optimized but $("#selector,a[name='selector']") won't go through the same optimizations as quickly. I suppose my 2.5 year old comment is a little strange sounding. The "optimization" is avoiding the a[name='selector'] search if it finds the id, not optimizing searching for the id.
  • Jonathan Dumaine
    Jonathan Dumaine about 11 years
    I at first thought Mandx was trolling, then I tried this and it worked. Beyond me how I never came across this method before. Mozilla Docs for this method. Also, it appears that this will be very well supported in browsers.
  • Jazzy
    Jazzy over 10 years
    I had some luck with this approach: <a data-hash="about">About</a> <script> $("[data-hash]").click(function() { var data = $(this).attr("data-hash"); $(document.body).animate({ 'scrollTop': $("#"+data).offset().top }, 500); }); </script>
  • Ryan
    Ryan about 10 years
    That doesn't actually scroll though, it just jumps. At that point you might as well just link to the anchor <a href="#anchorName">link</a>
  • NuclearPeon
    NuclearPeon almost 10 years
    I've had a lot of issues with jquery solutions not scrolling. This saved me a lot of frustration.
  • QUB3X
    QUB3X over 9 years
    @chrisツ It change the URL adding the "#anchor", right?
  • chris
    chris over 9 years
    @Qubex_ yes, I think so
  • Alveoli
    Alveoli over 9 years
    neat and does it without reloading the page. Thanks!
  • Cristian Vrabie
    Cristian Vrabie over 9 years
    Note that this will only work once. Once the hash is set, the page won't scroll to the same hash unless you change it to a dummy one then set it again.
  • nico gawenda
    nico gawenda over 9 years
    When you set the value, you have to omit the hash sign. "location.hash = hash;" - which also makes it pretty weird to wrap it in a function
  • Benny Schmidt
    Benny Schmidt almost 9 years
    @Ryan The question was about how to do it in javascript, not HTML.
  • jpaugh
    jpaugh almost 9 years
    Sometimes, you need to do it dynamically, though; i.e., through no direct action of the user. I believe that's what the OP wants.
  • Srneczek
    Srneczek over 8 years
    -one - it doesn't scroll
  • Bill Shihara
    Bill Shihara over 8 years
    The selector is throwing an exception in jquery 2.2.0. 0x800a139e - JavaScript runtime error: Syntax error, unrecognized expression: a[href*=#]:not([href=#])
  • Markus Zeller
    Markus Zeller over 8 years
    You should not use scrollTo, because it is already used by the global window object. Also the parameter should not be named hash, because location.hash is defined, too. You may use this code: function scrollToHash(hashName) { location.hash = "#" + hashName; }
  • AntBirch
    AntBirch almost 8 years
    Apologies for commenting on an old topic but this works best for me as my project isn't using JQuery. Only issue I noticed is that it misses off 5 pixels or so if you scroll to the very top.
  • Gherman
    Gherman over 7 years
    @MarkusZeller, why shouldn't the parameter be called hash? It doesn't collide with location, does it?
  • isherwood
    isherwood over 7 years
    Yes, clearly the OP was already aware of anchor link functionality.
  • Markus Zeller
    Markus Zeller over 7 years
    @German Oh, you're right. Hash is of course independent of the location object.
  • vogomatix
    vogomatix over 7 years
    WARNING! This method can have problems if a div above it contains floating elements and cannot determine its size easily.
  • nunop
    nunop over 7 years
    This is a clean solution, however as of now it doesn't allow any tweaking, it does a hard scroll. There is an experimental parameter scrollIntoViewOptions that has a behavior: "smooth" option, but it is currently compatible with Firefox only.
  • Dave Everitt
    Dave Everitt about 7 years
    Very refreshing to see a pure js version. I teach students to always look under the hood and understand what JQuery does for them, so this is a nice example.
  • Mark Barrasso
    Mark Barrasso over 6 years
    This should be the accepted answer: it is a pure js example AND it achieves the desired scrolling animation effect. I adjusted the timeout value to 20 and it works flawlessly.
  • R01010010
    R01010010 over 6 years
    Thank you I love pure javascript solutions
  • zai chang
    zai chang over 5 years
    Excellent answer that removes dependency on jQuery
  • Lying_cat
    Lying_cat almost 5 years
    How to animate this?
  • Alexandru Trandafir Catalin
    Alexandru Trandafir Catalin almost 5 years
    Wow! Works awesome!
  • stackers
    stackers almost 5 years
    this does scroll if you set "scroll-behavior: smooth;" on the html element
  • parismiguel
    parismiguel over 4 years
    I think you should add the following to CSS style file: css html { scroll-behavior: smooth; }
  • Smitty-Werben-Jager-Manjenson
    Smitty-Werben-Jager-Manjenson over 4 years
    Nice, simple to use solution. Thanks!
  • Vincent
    Vincent over 4 years
    @SkuraZZ Best to ask a new question for this, since I just came across this coincidentally. But in any case, you can use scroll-behavior: smooth. See developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior
  • TadLewis
    TadLewis over 4 years
    I had to remove the multiplication by .2; it then went directly to my element. This works great if you are placing your data via document writes and you need to navigate after the page has completed loading. Straight hash navigation from the URL doesn't work in that case. Stick it in an event listener for page load.
  • Debbie Kurth
    Debbie Kurth about 4 years
    Works in IOS just tested it.
  • gaborous
    gaborous almost 4 years
    In the latest Chrome release this is the only method I have found that consistently works. Thanks for the tip!
  • gaborous
    gaborous almost 4 years
    This solution works very very well! Thanks for sharing!
  • goat
    goat over 3 years
    Note that scrollIntoView suffers from the same problem scrollto(some px location) does - if the location of the element changes as you scroll, you will scroll to the wrong position. This can easily happen if you, for example, have unknown-dimension images loading while you're scrolling, which will push the scroll target element down, and your nice fancy scroll will stop short in an over-dramatized epic fail.
  • Nathan B
    Nathan B over 3 years
    sometimes this is not accurate... when the page has dynamic parts with lazy load
  • Nathan B
    Nathan B over 3 years
    I don't see any animation here
  • Peter Mortensen
    Peter Mortensen almost 3 years
    An explanation would be in order. E.g., what is the idea/gist? Please respond by editing (changing) your answer, not here in comments (without "Edit:", "Update:", or similar - the answer should appear as if it was written today).
  • Peter Mortensen
    Peter Mortensen almost 3 years
    What is "relitere"? Is there a typo?
  • Dave
    Dave over 2 years
    This CSS method works great for me and is super elegant!
  • Mikko Rantalainen
    Mikko Rantalainen over 2 years
    If you think you want smooth scroll you should use document.getElementById("xyz").scrollIntoView({block:"neares‌​t", behavior:"smooth"}); so that the user doesn't get forced smooth scroll if they have disabled that in browser settings. Safari doesn't support this so it will just snap into correct position without animation. You should use this instead of scrolling to given pixel offset because this honors e.g. scroll-margin properties automatically. Reimplementing support for scroll-margin would be pretty complex.
  • Mikko Rantalainen
    Mikko Rantalainen over 2 years
    Note that if you use web fonts with font-display: swap you may end up with slightly incorrect scroll offset if you measure the scroll position before the fonts are swapped in. And when you use font-display: swap the swapping is asyncronous and depends on client network speed, DNS servers, web font hosting CDN and client CPU power so it's practically random. The best you can do is to try to detect the event for font loading: stackoverflow.com/a/66739727/334451
  • clamum
    clamum almost 2 years
    Very sexy scroll