Browser scrollbar, position fixed, dropdown menu, and jumps
Firstly, let's see a small problem:
This is our situation:
I am using @radix-ui/themes for all the components;
The header is fixed positioned;
When the dropdown menu opens, it adds an overlay, which hides the scrollbar;
So the header's width is bigger, then it moves to right a bit;
If you observe it carefully, the image also moves a bit;
It's not a big problem, but we can fix it.
The idea is, always set the header's width to be window width - scrollbar width
, no matter there is scrollbar or not.
But how to calculate the width of the scrollbar? Different browsers have different scrollbars.
Easy. See this:
function getScrollbarWidth() {
const scrollDiv = document.createElement('div');
scrollDiv.style.width = '100px';
scrollDiv.style.height = '100px';
scrollDiv.style.overflow = 'scroll';
scrollDiv.style.position = 'absolute';
scrollDiv.style.top = '-9999px';
document.body.appendChild(scrollDiv);
const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
document.body.removeChild(scrollDiv);
return scrollbarWidth;
}
We show the scrollbar for a div, and the trick is, offsetWidth
includes the bar, but clientWidth
doesn't.
Then we can get the width without scrollbar:
const widthWithoutScrollbar = window.innerWidth - getScrollbarWidth()
After we use this width for body and the fixed header, everything is as still as night:
Enjoy! And try notenote.cc