프로젝트를 진행하면서 데스크탑 웹에서 정상적으로 보이는 화면이 태블릿 웹에서 깨지는 현상이 발생했다.
vh 단위를 사용해서 총 높이를 100vh로 설정을 했는데, 100vh는 태블릿 브라우저의 상단 탭과 브라우저, 일부 태블릿에서는 하단 네비게이션 바의 사이즈를 포함하는 문제가 있었다.
이 문제를 해결하기 위해 아래와 같은 방법을 적용했다.
모바일 스크린 문제 해결
const setScreenSize = () => {
let vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty("--vh", ${vh}px);
};
setScreenSize();
window.addEventListener("resize", () => setScreenSize());
이 함수는 브라우저 창의 높이를 기반으로 한 사용자 정의 뷰포트 높이 단위(vh)를 설정하는 역할을 한다.
자세히 살펴보면,
setScreenSize() 함수는 먼저 브라우저 창의 높이(window.innerHeight)를 가져와 1%를 계산하여 vh 변수에 저장한다.
그런 다음 document.documentElement.style.setProperty 메소드를 사용하여 CSS 변수 --vh의 값을 vh 변수의 값으로 설정한다. 이렇게 하면 --vh는 실제 뷰포트 높이의 1%에 해당하는 값을 가지게 된다.
setScreenSize() 함수를 처음 한 번 호출하여 초기 --vh 값을 설정한다.
마지막으로 window.addEventListener("resize", () => setScreenSize()); 코드를 통해 브라우저 창 크기가 변경될 때마다 setScreenSize() 함수가 호출되도록 한다.
이렇게 하면 창 크기가 변경될 때마다 --vh 값이 적절하게 업데이트돼서 뷰포트 높이가 정확하게 반영되어 앱의 레이아웃이 깨지지 않고, 사용자 경험을 향상시킬 수 있다.
height: calc(var(--vh, 1vh) * 100);
이 방법을 적용하고 다른 것 때문에 우연히 구글링을 하다가 동일한 기능을 하는 dvh라는 단위가 있다는 것을 알게 됐다.
dvh?
vh 단위는 유저에게 보이는 영역의 크기값을 참조하기 위해 2015년에 추가되었다. 하지만 브라우저 스크롤 시 주소 창의 크기 변화에 따른 뷰포트 영역의 크기 변화와 관련된 모호함 때문에, 2021년 dvh, lvh, svh 단위가 새로 추가되었다고 한다.
나중에 추가된 세 단위는 브라우저의 주소창 크기가 커졌을 때와 작아졌을 떄의 상황 각각을 명시적으로 반영한다. (정확히는 주소창뿐만 아니라, 브라우저의 모든 자체 UI의 크기 변화를 모두 반영한다.)
dvh (dynamic viewport height)
1dvh
유저에게 보이는 영역 높이의 1% 값. 브라우저 자체 UI의 크기가 바뀔 때마다 갱신된다.
dvh(dynamic viewport height)는 브라우저 자체 UI의 크기가 바뀔 때마다 새로운 값으로 갱신되어, 실제 유저가 보는 영역의 크기를 항상 반영할 수 있다.
dvh를 사용하면 요소 CSS 값 지정을 위해 window.innerHeight를 계속 읽어오지 않아도 된다.
주의 사항
dvh는 위에서 설명한대로 브라우저 자체 UI의 크기 변경 때마다 바뀌는 값이기 때문에, dvh로 설정한 요소들을 수직으로 배치하면 유저가 스크롤 할 때 스크롤 위치가 순간이동하는 부작용이 있을 수도 있다. 유저가 스크롤할 때 주소창 높이가 바뀌면서 dvh로 설정한 요소들의 높이값들도 동시에 바뀌기 때문이다.
연속 스크롤보다는 쇼츠나 릴스같은 점프 스크롤 상황, 또는 높이를 뷰포트의 100%로 차지하는 사이드 바 컴포넌트 등에 적합할 것 같다.
출처
https://stackoverflow.com/questions/36862334/get-viewport-window-height-in-reactjs
https://jisiq.com/css/css-vh-dvh-lvh-svh
'TIL' 카테고리의 다른 글
3001번 포트 설정법 & 모바일 스크린 문제 해결 (0) | 2024.03.07 |
---|---|
forwardRef: 자식 컴포넌트에 ref를 전달하기 (0) | 2024.02.22 |
VSCode tab키 입력시 emmet 기능 안될 때, emmet이 작동하지 않을 때 (0) | 2024.02.22 |
React를 왜 배우는가 (0) | 2024.02.12 |
기술면접 준비 (0) | 2023.11.26 |