프로젝트 에코노삡을 배포하며 특이한 이슈를 발견했다.
모바일 브라우저 100vh가 내가 생각한 대로 작동하지 않았다... 🥹🔫
로딩 후 첫 화면에서는 100vh가 화면에 벗어났고, 아래로 스크롤 시에 하단의 툴바가 사라지며 100vh가 화면에 꽉 찼다.
vh
, vw
는 데스크탑에서는 잘 작동하는데, 왜 모바일 브라우저에서는 아닐까?
모바일 기기에서는 동적 툴바(주소, 탭)의 유무에 따라 뷰포트 크기가 영향을 받는다.
뷰표트 크기는 변경될 수 있지만 vh
, vw
크기는 변경되지 않기 때문에, 높이가 100vh인 요소는 뷰포트에 다 담기지 않는다.
배포하지 않았다면 몰랐을 이슈!! 해결 방법을 찾아보았다.
body {
min-height: 100vh;
@supports (-webkit-touch-callout: none) {
min-height: -webkit-fill-available;
}
}
css 몇 줄로 해결이 가능하다니 매우 간편하다.
문제는 해당 방법을 사용하면 vh
단위를 사용하지 못한다는 것이다.
정확히 말하자면 사용은 가능하지만, vh가 하단의 네비게이션 영역 사이즈를 포함해 계산한 값이기 때문에 정확하지 않다. 사용하지 말아야 한다.
vh
는 화면을 채울 때 뿐만 아니라, 여러 경우에 사용되기 때문에 이 방법은 배제했다.
그리고 ios에만 적용되고, android는 여전히 이슈를 해결할 수 없다.
두 번째 방법은 window
의 resize
이벤트가 발생될 때마다 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
lvw
, lvh
, lvi
, lvb
, lvmin
, lvmax
2. Small Viewport
svw
, svh
, svi
, svb
, svmin
, svmax
3. Dynamic Viewport
dvw
, dvh
, dvi
, dvb
, dvmin
, dvmax
기존 데스크탑에서는 동적 툴바가 없기 때문에 lv
, sv
, dv
모두 기존의 vw
, vh
단위와 같아서 더욱 더 편리하다.
이제 새로운 뷰포트 단위와 함께 모바일 브라우저를 조금 더 편하게 개발할 수 있다! 심지어 해당 단위는 대부분의 최신 브라우저에 호환된다.
필요하다고 생각한 단위가 생긴 것이 너무 신기하네..!!
100vh problem with iOS Safari
The large, small, and dynamic viewport units
공감하며 읽었습니다. 좋은 글 감사드립니다.