Skip to content

Instantly share code, notes, and snippets.

@nasheomirro
Last active January 2, 2023 09:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nasheomirro/80bdf966ff979218b4ef32bf976d0abe to your computer and use it in GitHub Desktop.
Save nasheomirro/80bdf966ff979218b4ef32bf976d0abe to your computer and use it in GitHub Desktop.
react-hook: prevent body scrollbar from shifting layout
// Thank you SO
// https://stackoverflow.com/questions/13382516/getting-scroll-bar-width-using-javascript
export function getScrollbarWidth() {
// Creating invisible container
const outer = document.createElement("div");
outer.style.visibility = "hidden";
outer.style.overflow = "scroll"; // forcing scrollbar to appear
document.body.appendChild(outer);
// Creating inner element and placing it in the container
const inner = document.createElement("div");
outer.appendChild(inner);
// Calculating difference between container's full width and the child width
const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
// Removing temporary elements from the DOM
// @ts-ignore parent node is document
outer.parentNode.removeChild(outer);
return scrollbarWidth;
}
import { useLayoutEffect } from "react";
import { getScrollbarWidth } from "@/utils";
// this hook is a modified version from this blog:
// https://maxschmitt.me/posts/react-prevent-layout-shift-body-scrollable/
const scrollbarWidth = getScrollbarWidth();
const usePreventScrollShifting = () => {
useLayoutEffect(() => {
const setPaddingRight = (isScrollable: boolean) => {
console.log(isScrollable);
if (isScrollable) document.body.style.paddingRight = "0px";
else document.body.style.paddingRight = `${scrollbarWidth}px`;
};
const resizeObserver = new ResizeObserver(() => {
setPaddingRight(document.body.scrollHeight > window.innerHeight);
});
resizeObserver.observe(document.body);
return () => {
resizeObserver.unobserve(document.body);
};
}, []);
};
export default usePreventScrollShifting;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment