
ScreenRecording_01-11-2025 13-12-57_1.MP4
일반적인 데스크 탑 환경에서는 왼쪽 사진과 같이 모달이 출력 되면 당연히 백그라운드 (뒷 배경) 스크롤이 막힌다특히 모바일 환경의 사파리 브라우저에서는 오른쪽 영상과 같이백그라운드를 터치하면 스크롤이 동작한다. 하지만 그 당시에는 라이브러리에 종속된 문제여서 그런지 구글링을 통해서도 명확한 해결을 찾을 수 없었다.
항상 라이브러리를 고를 때는 사용자가 많은지와 gihHub의 이슈가 잘 관리되고 있는지를 고려해서 우선순위로 두라고 했다. 이전에는 와닫지 않았지만 이번에 뼈저리게 느끼게 되었다.
모든 코드가 그렇듯 처음부터 완벽하게 나올 수 없고 수정에 수정을 거친다. 그리고 수정을 거치더라도 완벽하지는 않을 것이다. 라이브러리도 코드인지라 개발자가 예상하지 못한 부분에서 이슈가 발생할 수 있으며 특히 antD는 사용자가 이슈를 오픈하고 또 이슈에 대한 답을 하기도 하는 활발한 라이브러리이다.
(AntD는 24년 2월 기준 UI 라이브러리 사용자 수 2위 이다)

이렇게 이슈가 거의 일간 단위로 오픈이 된다. 다 같이 문제를 공유하고 해결하는 것 개발의 장점 중 하나라고 생각한다. 이것도 개발을 시작하게 된 이유 중 하나가 아닐까 싶다 여튼 내가 겪은 이슈는 **ops1ops** 라는 분이 사파리 브라우저에서 발생하는 흔한 이유라고 하고 방법을 정의했다.
https://github.com/ant-design/ant-design/issues/23202
//index.css
.scroll-disabled {
overflow: hidden;
position: fixed;
}
문제는 modal이 열릴 때 위 속성이 제대로 적용이 안되는 것 때문에 발생한다.
우선 아래의 코드처럼 enable (CSS 속성이 적용 + 스크롤 위치 고정)되는 코드를 작성하고 이를 해재하기 위한 disable를 정의한다
// 현재 스크롤 위치를 저장하기 위한 변수
let scrollPosition = 0;
// body 요소를 참조하기 위한 변수
let body;
// 스크롤 비활성화를 위한 CSS 클래스 이름
const DISABLE_SCROLLING_CLASS = "scroll-disabled";
// 스크롤 락 기능을 제공하는 객체
// useScrollLock.disable(); -> 스크롤 락 해제
// useScrollLock.enable(); -> 스크롤 락 적용
export default {
// 스크롤 락 적용
enable() {
// 현재 스크롤 위치를 저장
scrollPosition = window.scrollY;
// body 요소를 선택
body = document.querySelector("body");
// body에 스크롤 비활성화 클래스를 추가
body.classList.add(DISABLE_SCROLLING_CLASS);
// 현재 스크롤 위치를 음수로 설정하여 화면을 고정
body.style.top = `-${scrollPosition}px`;
},
// 스크롤 락 해제
disable() {
// body 요소가 없을 경우(락이 적용되지 않은 경우) 아무 작업도 수행하지 않음
if (!body) {
return;
}
// body에서 스크롤 비활성화 클래스를 제거
body.classList.remove(DISABLE_SCROLLING_CLASS);
// body 요소에서 top 스타일 속성을 제거
body.style.removeProperty("top");
// 저장했던 스크롤 위치로 화면 스크롤을 이동
window.scrollTo(0, scrollPosition);
},
};
그리고 modal이 열릴 때 useScrollLock.enable() 을 적용하고 닫힐 때 useScrollLock.disable() 를 적용하여 속성들을 제거하는 코드를 작성한다
import React, { useState } from "react";
import { Button, Modal } from "antd";
import useScrollLock from "../helper/useScrollLock";
export default function Home() {
const [isModalVisible, setIsModalVisible] = useState(false);
const showModal = () => {
useScrollLock.enable();
setIsModalVisible(true);
};
const handleCancel = () => {
useScrollLock.disable();
setIsModalVisible(false);
};
return (
<div className="flex flex-col justify-center items-center h-[200vh]">
<h1 className="pb-10">Home</h1>
<Button type="primary" onClick={showModal}>
Open Modal
</Button>
<Modal
title="Ant Design Modal"
open={isModalVisible}
onCancel={handleCancel}
onOk={handleCancel}
>
<p>This is the content of the modal.</p>
</Modal>
</div>
);
}
그렇게 하면 스크롤이 정상적으로 잠기고 해제되며 백그라운드 스크롤이 막히게 된다.