모바일 브라우저에서 100vh가 왜 안 돼!!!! 🤯

modi·2023년 8월 11일
109
post-thumbnail

프로젝트 에코노삡을 배포하며 특이한 이슈를 발견했다.

모바일 브라우저 100vh가 내가 생각한 대로 작동하지 않았다... 🥹🔫

로딩 후 첫 화면에서는 100vh가 화면에 벗어났고, 아래로 스크롤 시에 하단의 툴바가 사라지며 100vh가 화면에 꽉 찼다.

vh, vw는 데스크탑에서는 잘 작동하는데, 왜 모바일 브라우저에서는 아닐까?

모바일 기기에서는 동적 툴바(주소, 탭)의 유무에 따라 뷰포트 크기가 영향을 받는다.

뷰표트 크기는 변경될 수 있지만 vh, vw 크기는 변경되지 않기 때문에, 높이가 100vh인 요소는 뷰포트에 다 담기지 않는다.

배포하지 않았다면 몰랐을 이슈!! 해결 방법을 찾아보았다.

-webkit-fill-available

body {
  min-height: 100vh;
  
  @supports (-webkit-touch-callout: none) {
    min-height: -webkit-fill-available;
  }
}

css 몇 줄로 해결이 가능하다니 매우 간편하다.

문제는 해당 방법을 사용하면 vh 단위를 사용하지 못한다는 것이다.
정확히 말하자면 사용은 가능하지만, vh가 하단의 네비게이션 영역 사이즈를 포함해 계산한 값이기 때문에 정확하지 않다. 사용하지 말아야 한다.

vh는 화면을 채울 때 뿐만 아니라, 여러 경우에 사용되기 때문에 이 방법은 배제했다.

그리고 ios에만 적용되고, android는 여전히 이슈를 해결할 수 없다.

css custom property

두 번째 방법은 windowresize 이벤트가 발생될 때마다 css custom property(--vh)를 설정하는 것이다.

에코노삡은 리액트로 진행되었기 때문에, 관련 로직을 커스텀 훅으로 생성했다.

function use100vh() {
  const handleResize = () => {
    const vh = window.innerHeight * 0.01;
    document.documentElement.style.setProperty("--vh", `${vh}px`);
  };

  useEffect(() => {
    window.addEventListener("resize", handleResize);
    return () => {
      window.removeEventListener("resize", handleResize);
    };
  }, []);
}

그리고 기존에 vh 단위 대신 calc(var(--vh, 1vh) * 원하는 크기)를 사용했다.

새로운 동적 단위

이렇게 3개월 전에 이슈를 해결했는데... 큰 반전이 일어났다! 최근 vh가 아닌 모바일의 동적 툴바를 고려한 새로운 뷰포트 단위가 생겼다. 🎉

1. Large Viewport

  • 동적으로 확장 및 축소되는 모든 UA 인터페이스가 축소된다고 가정한 뷰포트 크기
  • 스크롤을 내려서 기존의 동적 툴바가 사라진 뷰포트 크기
  • lvw, lvh, lvi, lvb, lvmin, lvmax

2. Small Viewport

  • 동적으로 확장 및 축소되는 모든 UA 인터페이스가 확장된다고 가정한 뷰포트 크기
  • 기존의 동적 툴바가 모두 나타난 뷰포트 크기
  • svw, svh, svi, svb, svmin, svmax

3. Dynamic Viewport

  • 동적 툴바가 확장되면 Small Viewport의 크기와 같다
  • 동적 툴바가 축소되면 Large Viewport의 크기와 같다
  • dvw, dvh, dvi, dvb, dvmin, dvmax

기존 데스크탑에서는 동적 툴바가 없기 때문에 lv, sv, dv 모두 기존의 vw, vh 단위와 같아서 더욱 더 편리하다.

이제 새로운 뷰포트 단위와 함께 모바일 브라우저를 조금 더 편하게 개발할 수 있다! 심지어 해당 단위는 대부분의 최신 브라우저에 호환된다.

필요하다고 생각한 단위가 생긴 것이 너무 신기하네..!!

참고자료

100vh problem with iOS Safari
The large, small, and dynamic viewport units

8개의 댓글

comment-user-thumbnail
2023년 8월 11일

공감하며 읽었습니다. 좋은 글 감사드립니다.

답글 달기
comment-user-thumbnail
2023년 8월 16일

이건 진짜 도움 되는 정보네요

답글 달기
comment-user-thumbnail
2023년 8월 17일

오오.. 감사합니다

답글 달기
comment-user-thumbnail
2023년 8월 18일

감사합니다!

답글 달기
comment-user-thumbnail
2023년 8월 18일

저는 실무 개발하면서 웹뷰에서 하위 버전에 대한 호환을 고려하는 것이 중요했었어요

늘 저도 같은 고민을 하고 있었기 때문에 쉽게 풀수 있는 새로운 단위는 저도 처음 봐서 너무 반가웠어요. 그런데 최신버전에만 적용할 수 있다는 것이 슬픕니다.

괜찮으시다면 구글에 env() 라는 webkit css fuction과 safe-area-inset margin을 찾아보시는 것을 추천드려요. 현업에서 노치대응할때에 웹 호환성을 고려하여 사용하는 방식입니다

1개의 답글
comment-user-thumbnail
2023년 8월 22일

dvh가 가장 이상적으로 보이지만
naver app 쪽에서 안먹히는듯합니다.

1개의 답글