본문 바로가기

프론트엔드

모바일 기기에서 scroll 관련 버그 대응하기

  • 프로젝트: 채식 지도
  • 키워드: viewport height, window.innerHeight, scrollbar, pull-to-refresh, overscroll-behavior
  • 상황
    1. 스크롤이 가능한 웹페이지를 moblie 기기에서 보면 예상치 못한 상황이 많이 일어난다.
    2. 그 중에서 1) vh가 viewport 보다 크게 잡히는 버그 2) scrollbar를 숨기고 싶은 상황 3) 안드로이드 기기의 pull-to-refresh 기능을 막고 싶은 상황을 대응하고자 한다.
  • 해결 방법
    1. height: 100vh에서 'vh' 단위는 'viewport height'를 의미하기 때문에 100vh는 브라우저 viewport의 높이와 일치해야한다.
      하지만 모바일 기기의 경우는 주소창(top bar)과 navigation bar(bottom bar)가 있기 때문에 vh의 viewport가 사용자의 눈에 보이는 viewport보다 크다.
      이 경우는 js의 window.innerHeight를 이용하면 해결할 수 있다.
        // NOTE: 모바일에 대응하기 위해 실제 viewport의 높이 계산
      const [viewportHeight, setViewportHeight] = useState(1000);
      useEffect(() => {
        setViewportHeight(window.innerHeight);
      }, []);
      const storeListHeight = useMemo(() => viewportHeight - ..., [viewportVh]);


    2. 스크롤바 UI를 숨기는 것이 보기에 더 깔끔한 경우, CSS를 이용하여 스크롤바를 숨길 수 있다.
        // 스크롤바 숨기기
      -ms-overflow-style: none;
      &::-webkit-scrollbar {
        display: none;
      }
       
    3. 웹사이트 안에서 스크롤 영역이 존재할 경우, 스크롤 영역의 최상단에서 화면을 아래로 당기면(swipedown) 웹페이지가 새로고침 되는 'pull to refresh' 제스쳐가 동작한다.
      웹사이트 중간에 있는 테이블, List 등의 스크롤 영역인 경우 pull-to-refresh gesture를 원하지 않을 수 있는데, 이 역시 CSS를 이용하여 방지할 수 있다.
        overscroll-behavior: none;
      스크롤 영역의 element에 직접 style을 입혀도 되고, 상위에 있는 element에 style을 입혀도 동작한다.

    4. 하단바나 상단바에 의해 높이가 변하지 않고, 스크롤바가 보이지 않으며, 스크롤 영역 최상단에서도 pull-to-refresh gesture가 동작하지 않는 것을 확인했다!

모바일 기기에서 스크롤