1

I am fighting with weird Chrome behavior, when page loads it jumps on the bottom of the page and then immediately back up to top.

Reproducible in

  • Chrome 84.0.4147.135 (Official Build)
  • Chromium 80.0.3987.162

Conditions

  • There must be a fragment in URL '#bottom' referencing an element on very bottom of the page
  • Javascript will try to scroll on the very bottom of the page as well using html.scrollTop

When both conditions are true then the problem happens. Page jumps on the bottom (there is a red div - it flashes red) and then immediately back on top (becomes white again).

When there is only '#bottom' fragment without javascript or only javascript without '#bottom' fragment all works as expected - page is red as it scrolls on the very bottom. It is only when both mechanisms are used that it does not work.

Expected behavior

  • Javscript scrollTop modifications jumps on the bottom - page stays red (works)
  • Fragment reference jumps on the bottom - page stays red (works)
  • Both scrollTop modification and fragment reference jumps on the bottom - page stays red (does not work)

Current behavior:

  • Page jumps on the bottom - becomes briefly red - and then jumps back up and stays white

Note: It appears that Chrome simply restores initial scroll position. When you start on the bottom and you hit "CTRL+R" it stays on the bottom. When you start on top and hit CTRL+R then it stays on top while briefly jumping on the very bottom of the page.

Simplified code:

<!DOCTYPE html>
<html>
    <body>
    <!-- Just a button that makes sure there is '#bottom' fragment in URL, resets scrolling and reloads page -->
    <a href="javascript:location='#bottom';document.documentElement.scrollTop=0;location.reload();" style="position: fixed;">
            CLICK TO TEST
            <div><small>Keep clicking and if you see RED BACKGROUND FLASH you can reproduce the problem.</small></div>
    </a>

    <!-- Two big divs with distinct colors so we can see color flash when it jumps -->
    <div id="top" style="background: white; height: 10000px;"></div>
    <div style="height: 500vh; background-color: red;"></div>

    <!-- bottom target referenced by '#bottom' above -->
    <div id="bottom">BOTTOM ANCHOR</div>

    <script type="text/javascript">
            document.documentElement.scrollTop = document.documentElement.scrollHeight;
    </script>
    </body>
</html>

I could not use the inline preview because it needs URL with fragment. You can temporarily see it live here.

Edit: Observation - the whole issue appears to be Chrome trying to preserve old scrollTop position despite Javascript changing it to new one.

elixon
  • 1,123
  • 12
  • 15
  • 1
    I can also reproduce in Firefox 80. – D. Pardal Aug 24 '20 at 19:59
  • I could not reproduce it in FF so I though that I incorrectly described the expected behavior. If the page stays at the end "RED" - it works. If it stays at the end "WHITE" then there is the problem I am describing. Sorry for confusion and thanks for testing! – elixon Aug 24 '20 at 20:11

1 Answers1

1

It is not a bug. What's happening is:

  1. The page is scrolled down because of JS seting the hash of the URL.
  2. The page is scrolled up because of JS setting the scrollTop property.
  3. The page reloads (takes some time).
  4. Because the hash is still #bottom, once the browser finds and element with ID bottom, it scrolls to it.

I don't know what the best way is for you to fix this, but this seems to work:

javascript:location.hash='#bottom';document.documentElement.scrollTop=0;undefined;
D. Pardal
  • 6,173
  • 1
  • 17
  • 37
  • ad 1. you don't need to click, just keep hitting CTRL+R; ad 2. scrollTop actually jumps on very bottom (I added console.log() messages check out your Javascript console) The issue is that both javscript and URL hash should end up on bottom. When I run it in both Chrome and Firefox, Chrome settles on white page (incorrect) and FF on red page (correct). – elixon Aug 24 '20 at 20:18
  • Note: when hitting CTRL+R you need to scroll on very top first. It seems that Chrome simply restores the original position on page load erasing any changes mad by the use of URL fragment or scrollTop JS. – elixon Aug 24 '20 at 20:22