개발 기술/사소하지만 놓치기 쉬운 개발 지식

[CSS/JS] vh 버그 해결방법(dvh 사용법, js 계산법)

by GicoMomg (Lux) 2022. 7. 17.

🙂 CSS에서는 뷰포트를 기준으로 하는 vh, vw 단위가 존재하는데, 이 단위들은 일부 환경(ex. 모바일 safari)에서 문제가 있다. 이번 시간에는 해당 문제는 무엇이며, 해결방안으로 JS를 이용한 방법새로운 단위인 dvh를 이용하는 방법에 대해 알아보았다


1. vh, vw?

1) vh, vw는 무엇인가요?

  • vh, vwviewport(화면 크기)를 기준으로 하는 단위로, viewport크기에 따라 변경된다.
  • vh : viewport height, 1vh는 뷰포트의 높이의 1%이다.
  • vw : viewport width, 1vw는 뷰포트의 너비의 1%이다.

🙂 그런데, 이 vh, vw는 어떤 경우에 사용하면 좋나요?

  • 모바일 브라우저의 경우, 사용자 스크롤에 따라 일부 UI(ex. 검색, 주소창)가 축소된다.
  • 이때, 일부 UI가 축소되었을 때 표시하는 컨텐츠 영역을 늘리고 싶다면 vh를 사용할 수 있다.



2) vh에 버그(?)가 있다

☹️ 그런데…이 vh단위… 버그가 있다!

  • 우리가 높이를 100vh로 설정했을 때, 모바일 safari에서 vh를 결정할 때 일부 UI를 무시하는 버그가 있다.
  • vh는 가장 큰 viewport를 선택하므로, height: 100vh로 지정시 페이지가 로드됐을 때 높이가 화면 넘치게 지정되는 현상이 발생한다.
  • 결국, 해당 현상으로 인해 의도한 높이보다 더 큰 높이가 적용된다.ㅠ

WebKit에 작성된 vh overflow 버그 리포트




2. vh 버그 해결방법

🙂 vh 버그를 해결할 수 있는 방법에는 “JS에서 vh를 계산하는 방법”과 새로운 단위인 “dvh를 이용한 방법”이 있다. 차례대로 알아보자!

1) JS로 vh 계산하기

(1) JS에서 커스텀 vh 만들기

const vh = window.innerHeight * 0.01;   // [1]
document.documentElement.style.setProperty('--vh', `${vh}px`); // [2]
  • 첫 번째 방법으로, js에서 vh를 다시 계산해주는 방식이다.
  • 먼저, js에서 window의 innerHeight에 0.01를 곱하여 새로운 vh단위를 구한다. [1]
  • 그 다음, setProperty를 이용해 새롭게 구한 vh값을 —-vh 변수에 담는다. [2]

(2) CSS에 커스텀 vh 적용하기

.my-element {
  height: 100vh; /* [3] */
  height: calc(var(--vh, 1vh) * 100);  /* [4] */
}
  • 그 다음, vh를 사용하고자 하는 요소의 높이를 지정해준다.
  • 만약 특정 브라우저에서 —-vh가 작동되지 않을 수도 있으므로 height: 100vh를 한다. [3]
  • 그 다음에 height—-vh를 사용해준다. [4]

(3) 화면 크기 변경 대응하기

window.addEventListener('resize', () => {
  const vh = window.innerHeight * 0.01;
  document.documentElement.style.setProperty('--vh', `${vh}px`);
});
  • 만약 viewport의 높이가 변경될 때마다 --vh의 값을 업데이트하고 싶다면, resize이벤트를 이용하자.
  • 단, 높이가 변경될 때마다 —-vh값을 업데이트하면 화면이 점프될 수 있기에 상황에 맞게 사용해야한다.



2) dvh 사용하기(호환성 체크 필요)

🙂 dvh에 대해 알기 위해서는 svh, lvh에 대해서도 알아야 하는데 같이 알아보자

(1) svh(Short Viewport Height)란?

  • svh는 사용자가 볼 수 있는 가장 작은 viewport 높이를 반영한다.
  • viewport 높이에서 모든 인터페이스 요소를 제거한 높이라고 할 수 있다.

(2) lvh(Large Viewport Height)란?

  • lvh는 사용자가 볼 수 있는 가장 큰 viewport 높이를 반영한다.
  • viewport 높이에서 모든 인터페이스 요소를 포함한 높이라고 할 수 있다.

(3) dvh란?

  • dvh는 현재 viewport 높이를 나타내는 동적인 값이다. (100svh ≤ dvh ≤ 100lvh)
  • 만약 주소표시줄이 축소된 상태에서 스크롤을 통해 주소표시줄이 확장되면 dvh의 값도 업데이트된다.
  • dvh를 사용하면 정확히 viewport에 맞게 콘텐츠의 크기를 조정할 수 있다.

😖 단, 사용자가 스크롤을 하는 동안 콘텐츠의 크기가 조정될 수 있기에 편의성, 성능 면에서 비용이 발생할 수 있으므로 사용시 유의하자!



반응형

댓글