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.