모바일 화면에서 100vh의 문제
모바일 웹 앱에서 풀사이즈 화면을 만들어야 할 일이 있었습니다. 그래서 100vh를 사용했음에도 불구하고 모바일 chrome과 safari에서는 컨텐츠가 브라우저 세로 크기보다 커서 스크롤이 생기는 문제가 생겼습니다. 이 문제 때문에 많은 개발자들이 고통받고 있었습니다.
오랜 시간이 지나서야 dvh와 같은 새로운 단위가 추가되어 문제를 쉽게 해결할 수 있게 되었습니다.
Viewport란?
MDN 문서에 의하면 Viewport란 컴퓨터 그래픽스 분야에서 현재 보이는 화면 영역을 의미합니다.[1] 그리고 웹 브라우저 용어로는 일반적으로 UI, 메뉴 바, 등을 제외한 브라우저 창의 영역입니다.
Viewport 사이즈 상대 길이 단위: vh, vw
1 vh는 Viewport 높이의 1%를 의미합니다. 예를 들어 80 vh는 Viewport 높이의 80%를 의미합니다. 만약 Viewport 높이가 1080 px라면, 1 vh는 1080 px의 1%인 108px, 80 vh는 1080 px의 80%인 864 px입니다.
1 vw는 Viewport 너비의 1%를 의미합니다. 예를 들어 40 vw는 Viewport 너비의 40%를 의미합니다. 만약 Viewport 너비가 1920 px라면, 1 vw는 1920 px의 1%인 192px, 40 vw는 1920 px의 40%인 768 px입니다.
문제점
![iOS Safari에서 본 100vh](/cdn/articles/css-viewport-units/0697e69c-e8c3-41ce-9735-d54ea45add19.jpeg)
![iOS Chrome에서 본 100vh](/cdn/articles/css-viewport-units/93315e37-2ea1-44b8-bb86-92e8dcf88297.jpeg)
![macOS chrome에서 본 100vh](/cdn/articles/css-viewport-units/9263b728-b5fd-466c-80bb-d81050cb09a6.png)
모바일 웹에서 Viewport 사이즈를 100vh로 설정하면 브라우저의 일부 UI가 무시되어 의도한 것 보다 더 큰 영역이 Viewport 사이즈로 잡힙니다. 그 결과 의도했던 것 보다 세로로 더 길게 화면이 생성되고 스크롤이 생기는 문제가 발생합니다.
새로운 Viewport 사이즈 상대 길이
이러한 문제를 해결하기 위해 dvh, dvw라는 개념이 나왔습니다. vh 대신 dvh를 사용합니다.
동적인 Viewport 사이즈 상대 길이 단위: dvh, dvw
dvh, dvw는 Viewport 사이즈 변화에 따라서 동적으로 변화하는 단위입니다.
![출처: GoogleIO 2022 (link)](/cdn/articles/css-viewport-units/6dee6301-772a-4ae4-80fc-a2d2270a6036.png)
모바일 브라우저에서 스크롤을 하면 Viewport 사이즈가 동적으로 svh ~ lvh, svw ~ lvw 사이로 변화합니다. 이 사이즈를 각각 dvh, dvw로 구할 수 있습니다. 그래서 dvh와 dvw를 사용하면 꽉 찬 모바일 웹 화면을 보다 안정적으로 구현할 수 있습니다.
![iOS Safari에서 본 100 dvh](/cdn/articles/css-viewport-units/27f92e11-4eb9-4d25-a039-7a93413bb869.jpeg)
![iOS Chrome에서 본 100 dvh](/cdn/articles/css-viewport-units/e02330f6-d2ff-4281-8f86-97638eb18086.jpeg)
![macOS Chrome에서 본 100 dvh](/cdn/articles/css-viewport-units/cd34d688-b15f-4466-b4c8-2fc9f4ba79a2.png)
Viewport 최소 사이즈 상대 길이 단위: svh, svw
Viewport 최소 사이즈는 브라우저에서 가장 작게 인식될 수 있는 Viewport 크기를 의미합니다.
![iOS Safari에서 본 100 svh](/cdn/articles/css-viewport-units/f1a7842e-4356-4eff-a34c-e02473e223f4.jpeg)
![iOS Chrome에서 본 100 svh](/cdn/articles/css-viewport-units/5ce8bfac-282f-4eba-b2f7-8f2b591e8232.jpeg)
![macOS Chrome에서 본 100 svh](/cdn/articles/css-viewport-units/74c075bd-de96-409a-9b11-a28de4402546.png)
Viewport 최대 사이즈 상대 길이 단위: lvh, lvw
Viewport 최대 사이즈는 브라우저에서 가장 크게 인식될 수 있는 Viewport 크기를 의미합니다.
![iOS Safari에서 본 100 lvh](/cdn/articles/css-viewport-units/08eaf3a8-7371-421a-839a-5d1c92b52bc2.jpeg)
![iOS Chrome에서 본 100 lvh](/cdn/articles/css-viewport-units/e10e9b96-d500-4852-bacf-1c8d5e25b0d1.jpeg)
![macOS Chrome에서 본 100 lvh](/cdn/articles/css-viewport-units/7fbc35e2-47e6-4366-b18c-c6c2913fa198.png)
브라우저 호환성 확인
대부분의 최신 브라우저 (22년 중순 ~ 말 출시)에서 dvh와 dvw를 지원합니다.[2] 그러나 구형 브라우저 (22년 중순 이전 출시)에서는 지원하지 않기 때문에 사용에 주의가 필요합니다.
테스트용 프로젝트
![notion image](/cdn/articles/css-viewport-units/e4c6f2e9-78a8-4a02-a711-f4e4cca987f7.png)
NextJS로 만든 Viewport 상대 길이 단위 테스트 프로젝트입니다. yarn dev로 서버를 실행할 수 있습니다.
viewport-test-app
wodndb • Updated Jun 29, 2023
참고자료
[1] What is a viewport?, Viewport concents, MDN web docs, link
[2] Samll, Large, and Dynamic viewport units, Can I use…, link