Hyunjung Im

골칫덩이 vh의 문제점을 해결해줄 dvh, lvh, svh에 대해 정리해본다.


동적인 height를 가진 모바일 브라우저

mobile-safari

모바일 브라우저에서는 보통 스크롤 발생시 주소 표시줄이 사라지고, 다시 나타날 때 뷰포트 높이가 변하는 경우가 있다. 이때 뷰포트 높이를 기준으로 하는 단위를 사용하면 뷰포트 높이가 변할 때마다 레이아웃이 깨지는 문제가 발생할 수 있다.

100vh의 문제점

  • 100vh를 차지하고 하단에 고정된 요소가 있을 때, 주소 표시줄이 사라지면 뷰포트 높이가 줄어들어 하단에 고정된 요소가 화면 밖으로 사라지는 문제가 발생한다.

vh 변수 설정 + resize 이벤트로 해결하기

  • vh는 한 번 계산되고 끝이기 때문에 모바일에서 동적으로 변화하는 height를 계산하기 위해서는 JS를 사용해 동적 height값을 사용해 일일히 계산이 필요하다.
useEffect(() => {
  const updateVh = () => {
    const vh = window.innerHeight * 0.01
    document.documentElement.style.setProperty('--vh', `${vh}px`)
  }

  updateVh()
  window.addEventListener('resize', updateVh)

  return () => window.removeEventListener('resize', updateVh)
}, [])
/* css 설정 */
.mobile-element {
  height: calc(var(--vh, 1vh) * 100);
}
<html style="--vh: ~px;">
  <!-- //... -->
</html>
  • setProperty로 설정하면, 개발자 도구에서 style에 --vh가 추가되어 있는 것을 확인할 수 있다.

vh 변수 해결 방식의 문제점

성능 저하

  • 과도한 리렌더링: resize 이벤트는 브라우저 창 크기가 변경될 때마다 발생하므로, 불필요한 리렌더링이 빈번하게 발생할 수 있음
  • 레이아웃 스래싱: resize 이벤트 핸들러에서 요소의 크기를 읽고 스타일을 변경하면, 브라우저가 레이아웃을 반복적으로 계산해야 하므로 성능이 저하될 수 있음

모바일 브라우저의 고통에서 구해줄 dvh, lvh, svh

Viewport Height Units (vh, svh, dvh, lvh)

  • 뷰포트 높이를 기준으로 하는 단위
단위설명특징
vhViewport Height의 1%브라우저 창의 높이를 기준으로 함
svhSmall Viewport Height의 1%모바일 기기에서 주소 표시줄 등을 제외한 최소 뷰포트 높이
dvhDynamic Viewport Height의 1%모바일 기기에서 주소 표시줄 표시 여부에 따라 동적으로 변하는 뷰포트 높이
lvhLarge Viewport Height의 1%모바일 기기에서 주소 표시줄 등을 포함한 최대 뷰포트 높이

사용 예제

.box {
  height: 100vh; /* 기본 뷰포트 높이 */
}

.box-svh {
  height: 100svh; /* 최소 뷰포트 높이 */
}

.box-lvh {
  height: 100lvh; /* 최대 뷰포트 높이 */
}

.box-dvh {
  height: 100dvh; /* 동적 뷰포트 높이 */
}
  • dvh의 경우 뷰에 따라 뷰포트 높이가 변하므로, 스크롤이 발생하지 않는 Full 사이즈의 뷰에서는 svh를 사용하는 것이 성능적으로 유리할 수 있다.

support로 하위 버전, 상위 버전 구분하기

/* svh 지원하지 않는 하위 버전은 100vh 사용 */
@supports not (height: 100svh) {
  height: calc(var(--vh, 1vh) * 100);
}

/* svh를 지원하는 상위 버전은 svh 사용 */
@supports (height: 100svh) {
  height: 100svh;
}
  • support를 사용해 하위 버전과 상위 버전을 구분하여 사용할 수 있다.

지원 범위

아쉽게도.. 사파리에서는 v16.4 부터 지원된다. 회사 지원 버전이 v17부터면 좋겠지만.. 결국 위 vh 변수 설정 방식과 함께 사용해야만 한다.

iOS Versions Market Share in 2025 링크에서 보면 2025년 01월 25일을 기준으로 iOS 16 버전 이하의 점유율은 5프로 정도이다.


참고