Firefox not scrolling to Anchor Links Tags position (Solution)

Go straight to the solution

Issue

When clicking on an internal link, Firefox doesn’t scroll to the position of the anchored / hashtag / # element, during the first page load. Instead, it jumps to the middle or to the bottom of the page. If user clicks inside of the address bar and presses Enter, Firefox then scrolls to the correct position. Problem only occurs when link is not on the same page as the anchored element. If both are on the same page, Firefox scrolls to the correct position. Bug is not present in other browsers.

Example: If you click on link – GetGui DC charging adapter with ammeter New tab opens and Firefox should scroll directly to the element with ID “getgui-current-measuring-adapter”. Instead it scrolls to the middle or to the bottom of the page, as seen in the screenshot below.

firefox-anchor-link-scroll-bug

Problem occurs because Firefox tries to scroll to the anchored element before the page is even loaded and the element is actually created. Since it can’t locate the anchored element, it scrolls to the middle or to the bottom of the page.

Solution

Workaround takes advantage of the Javascript’s window.onload event handler, location.hash property and scrollIntoView method. All three are supported in all the major browsers.

Function is simple and straightforward, as seen below.

...
<script>
/*location.hash returns the anchor part of an URL as a string, 
with hash (#) symbol included. */
//wait for page elements to load
//execute function only if the anchor exists in the URL address
window.onload = function() {if(location.hash){
    //remove # from the string
    var elId = location.hash.replace('#','');
    //locate the anchored element on the page by its ID property 
    var scrollToEl = document.getElementById(elId);
    //scroll to the anchored element
    scrollToEl.scrollIntoView(true);   
}
 }
</script> 
</body>
</html>

Copy the code below and paste it inside of every page, just above the closing body tag, as seen in the example above.
Note: Code can be copied just to the footer element, if the same footer is shared between the pages.

<script>
window.onload = function() {if(location.hash){
    var elId = location.hash.replace('#','');
    var scrollToEl = document.getElementById(elId);
    scrollToEl.scrollIntoView(true);   
}
 }
</script>

Below is a modified code contributed by the user Thor

One very slight mod to prevent a javascript error when your URL contains a hash but the element does not exist on the page (odd case, I know… but working on a site where this was important). It won’t scroll, but also won’t error now. Your code snippet was a life saver… so many answers out there that do not work. Thanks!

<script>
window.onload = function() {
if(location.hash){
var elId = location.hash.replace(‘#’,);
var scrollToEl = document.getElementById(elId);
if(scrollToEl) scrollToEl.scrollIntoView(true);
}
}
</script>


If you have found this blog post useful and would like to buy me a cup of coffee, please click here :)

15 thoughts to “Firefox not scrolling to Anchor Links Tags position (Solution)”

  1. Thank you. This works like a charm! I was looking for a solution for quite a few hours and your suggestion solved my problem. Thanks!

  2. Thank you. This didn’t work for me, but helped me figure out a hack that does work, albeit not beautifully.

    The reason your fix didn’t work is that Firefox apparently triggers the load even before it scrolls to the hashtag location. So your function was working and scrolling to the right location, but then being immediately overridden by Firefox completing its hashtag scroll to the wrong location.

    The only way I could figure out how to fix the issue was with a delay timer. This is a bit ugly as Firefox still scrolls to the wrong location which remains on screen till the timeout calls the function to scroll to the right location. So there’s a visible flash.

    Anyhoo, here’s the code I’m using, for anybody troubled by the same problem.

    window.addEventListener (“load”, myFirefoxFix, false);
    function myFirefoxFix () {
    if ((location.hash) && (typeof InstallTrigger !== ‘undefined’)) {
    setTimeout(myFirefoxHashScroller, 1);
    }
    }
    function myFirefoxHashScroller () {
    var elId = location.hash.replace(‘#’,”);
    var scrollToEl = document.getElementById(elId);
    scrollToEl.scrollIntoView(true);
    }

    1. Hi Tom,

      I have tested my solution in the latest Firefox (v54.0.1) and it still works for me without issues.

      Thank you for posting your solution in the comments.

  3. very very thans to below script worked correctly.

    window.onload = function() {if(location.hash){
    var elId = location.hash.replace(‘#’,”);
    var scrollToEl = document.getElementById(elId);
    scrollToEl.scrollIntoView(true);
    }
    }

    1. Hi Rajavel,

      I’m glad that it works and thank you for your feedback.

      Best Regards,
      Simon

  4. Thank You. I have tested all above solution but didn’t work for me. Untill i see a best solution from Stackoverflow, Here’s the code I’m using to set the timer with a minimum delay

    if (window.location.hash.length > 0) { setTimeout(function() { window.scrollTo(0, $(window.location.hash).offset().top); }, 100); }

    1. After trying many other solutions, this is the only snippet that worked for me as well. However, I had to adjust the timeout to something between 400-500 ms to achieve consistent behavior between FF and CH. Anything under wouldn’t give enough time to scroll to section in FF, and more time was too long of a pause before scrolling.

  5. After almost 10 different hints that failed this one finally works! Thanks a lot!!!

  6. One very slight mod to prevent a javascript error when your URL contains a hash but the element does not exist on the page (odd case, I know… but working on a site where this was important). It won’t scroll, but also won’t error now. Your code snippet was a life saver… so many answers out there that do not work. Thanks!

    window.onload = function() {
    if(location.hash){
    var elId = location.hash.replace(‘#’,”);
    var scrollToEl = document.getElementById(elId);
    if(scrollToEl) scrollToEl.scrollIntoView(true);
    }
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.