모달창이 열려있을 때 body 스크롤 방지하기
useEffect
를 사용하여 컴포넌트 마운트/언마운트
시 스타일을 지정한다.overflow: hidden
으로 지정해서, 스크롤바를 숨긴다.// components/login/LoginModal.tsx
useEffect(() => {
document.body.style.overflow = 'hidden';
return () => {
document.body.style.overflow = 'unset';
};
}, []);
👎 스크롤바 자체가 사라지면서, 스크롤바의 너비만큼(16px 정도) 윈도우 내부 사이즈가 변한다.
overflow: scroll
이므로 스크롤바가 사라지지 않는다.// utils/modal.ts
/**
* 스크롤을 방지하고 현재 위치를 반환한다.
* @returns {number} 현재 스크롤 위치
*/
export const preventScroll = () => {
const currentScrollY = window.scrollY;
document.body.style.position = 'fixed';
document.body.style.width = '100%';
document.body.style.top = `-${currentScrollY}px`; // 현재 스크롤 위치
document.body.style.overflowY = 'scroll';
return currentScrollY;
};
/**
* 스크롤을 허용하고, 스크롤 방지 함수에서 반환된 위치로 이동한다.
* @param prevScrollY 스크롤 방지 함수에서 반환된 스크롤 위치
*/
export const allowScroll = (prevScrollY: number) => {
document.body.style.position = '';
document.body.style.width = '';
document.body.style.top = '';
document.body.style.overflowY = '';
window.scrollTo(0, prevScrollY);
};
// components/login/LoginModal.tsx
useEffect(() => {
const prevScrollY = preventScroll();
return () => {
allowScroll(prevScrollY);
};
}, []);
✅ 스크롤바가 사라지지 않고, body의 위치를 고정함으로써 스크롤을 방지한다.
Reference
React에서 Modal 구현하기(feat. createPortal, 스크롤 막기)
[Web Study - CSS]모달창 스크롤 막기
효진님!! 우연히 보게되어 반가웠어요!!
잘 보고 갑니다 :)