I have a straightforward scroll to top button via anchor tag, and it works as expected. Except for one issue which I’ll try to describe the best I can how I’ve observed it:
- I scroll with mouse wheel all the way to the bottom
- I put enough speed in the wheel that if bottom was not reached, the scroll would go lower. To me it feels like as if there was still some scrolling left to do. For argument sake, lets say there would’ve been another 100px left to scroll if not for bottom.
- At this point I am the bottom of page and I click scroll to top button and it’s stuck! It starts to scroll to top by like 10-20px and then goes back to bottom
- I can continue clicking this and eventually it will scroll normally to top
- I’m not sure, but I feel like the issue is that since there was still 100 px to scroll towards bottom, and it starts to scroll to top, theres this conflict where scrollbar goes a bit higher from the bottom and immediately the 100px that were not scrolled to bottom, start to scroll down.
- So there is this jerky up and down situation going on until the 100px downwards have been scrolled, after which it scrolls normally to top. Lets say 20px on each click so 5 clicks to 100. This is what it feels like, though I’m not sure.
I’m sure others have observed this behavior as well? How do I fix this? My first thought was to try to find programmatically can I “clear the unscrolled reserve” but I could not find an answer for this.
For context, smooth scrolling is enabled through css via :root {scroll-behavior: smooth;}
Here is the ScrollToTop component code.
'use client';
import React, { useEffect } from 'react';
import { ArrowIcon, CreateIcon } from '../../JsxIcons';
import { debounce } from '../../utilities/functions';
const ScrollToTopButton = (): JSX.Element => {
const handleScroll = debounce(() => {
console.log(window.scrollY);
}, 200);
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, [handleScroll]);
return (
<a
href='#'
role='button'
aria-label='Scroll to top'
className='fixed top-[90vh] right-[5vh] size-12 block'
>
<CreateIcon path={ArrowIcon} />
</a>
);
};
export default ScrollToTopButton;