티스토리 뷰

css style 중 overflow는 상자에 맞추어 내용물을 조정할 수 있는 코드이다. 예를 들어 이런식으로 말이다.

https://developer.mozilla.org/en-US/docs/Web/CSS/overflow
https://developer.mozilla.org/en-US/docs/Web/CSS/overflow

overflow 속성 중에 'hidden'이라는 속성은 상자에 맞게 콘텐츠가 잘리는 속성으로 스크롤 막대가 제공되지 않으며, 사용자의 스크롤 액션을 막아준다.

https://developer.mozilla.org/en-US/docs/Web/CSS/overflow

그래서 많은 실무자들이 모달 등을 띄웠을 때, 배경이 스크롤 되지 않게 하기 위하여 overflow: hidden을 통해 스크롤을 막아준다.

여기서 문제는 overflow: hidden은 모바일 사파리에서 지원되지 않는다는 점이다. 사파리 렌더링 엔진인 Webkit의 버그라고 한다. (혹시나 그럴리가 없는데? 우리는 overflow hidden을 통해서 스크롤을 잘 막고 있었는데?! 라고 생각하는 서비스가 있다면 두 손가락으로 스크롤을 진행해보아라- 거의 높은 확률로 스크롤이 된다. 혹시나 안 된다면 아마 스크롤 할 영역이 적기때문에 스크롤이 안 되는 것이다.)

이를 해결하기 위한 방법은 정말 다양하다. 구글에만 검색해도 많이 나온다! 그 중에서 나는 가장 오류 날 확률이 적다고 하는 방식을 채택하여 풀어내었다. (가장 오류 날 확률은 적지만 다른 방법에 비하여 코드는 제일 길다.)

스크롤 막는 함수.js

const bodyScrollLock = () => {
  const bodyElement = document.querySelector('body');
  const scrollPosition = window.pageYOffset;
  
  body.style.position = 'fixed';
  body.style.top = `-${scrollPosition}px`;
  body.style.left = '0';
  body.style.right= '0';
  // 하단 코드는 생략 가능
  bodyElement.style.overflow = 'hidden';
  bodyElement.style.pointerEvents = 'none';
}

body에 overflow 스타일을 적용시키는 대신에 position을 fixed로 설정하는 방법이다.

다만, position fixed는 스크롤을 아예 없애는 의미이기 때문에 적용시키면 스크롤 좌표가 최상단으로 이동하는 이슈가 존재한다. 이를 해결하기 위하여 해당 스타일을 적용시키기 전 window.pageYOffset으로 현재 스크롤 위치를 기억한다. 이후 fixed를 적용시키고, top의 위치를 -window.pageYOffset (기억하고 있는 Y좌표)로 적용시키면 스크롤이 이동되지 않고, 현재에 멈춰있는 것 처럼 보인다.

더불어 overflow: hidden과 pointerEvents: none은 굳이 넣지 않아도 기능에는 문제가 없으나 이중 삼중으로 스크롤을 막기위하여 추가해둔 사항이다.

 

막힌 스크롤을 해제하는 함수

const bodyScrollUnlock = () => {
  const bodyElement = document.querySelector('body');
  const scrollPosition = window.pageYOffset;
  
  body.style.removeProperty('position');
  body.style.removeProperty('top');
  body.style.removeProperty('left');
  body.style.removeProperty('right');
  
  body.style.removeProperty('overflow');
  body.style.removeProperty('pointer-events');
  
  window.scrollTo(0, scrollPosition);
}

스크롤언락 해제는 비교적 간단한데, 설정했던 모든 속성들을 제거하여주면 된다.

이때, 상단에 언급한 것과 같은 현상인 스크롤 이슈가 있기 때문에 기억해둔 스크롤 좌표를 window.scrollTo 함수를 통하여 원복시켜주는 과정이 필수적으로 필요하다.


여타 다른 해결책들 중에 스크롤 라이브러리를 사용하라는 의견도 많은데, 내가 사용했던 가장 유명한 body-scroll-lock 라이브러리 기준으로 IOS 버그가 패치되어 beta 버전으로 릴리즈 되어있다고는 하지만 해당 버그가 여전히 잔존하는 상태이며, 이슈도 열려있다. 이슈의 댓글들을 확인해보니 1년이 넘게 해당 버그를 수정하지 않고 있다고 한다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함