모바일 브라우저의 뷰포트

visualViewport API를 사용한 반응형 웹

모바일 브라우저의 position: absolute

모바일 브라우저에서 다음과 같은 CSS position 속성은 의도치 않은 동작을 일으킨다:

div#container {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

모바일 웹에서 확인: kidk.kr/visual-viewport-example/static.html

모바일 브라우저에는 여러 툴바와 주소창, 그리고 키보드영역이 존재한다. 대부분의 경우 웹페이지는 정적이기 때문에 브라우저의 보이는 영역이 작아진다고 해서 매번 그 크기에 맞추어 페이지를 재렌더링하는 것은 불필요한 일이다. 왜냐하면 모바일 브라우저의 뷰포트는 잦은 빈도로 리사이징이 일어나기 때문이다.

위 코드를 작성한 사람은 아마도, 모바일 브라우저 내에서 보이는 화면을 꽉 채운 div 엘리먼트를 구현하려고 했겠지만, 사실상 키보드가 올라오거나 스크롤이 일어나 iOS Safari의 툴바가 올라오면 원치않는 레이아웃을 발견할 것이다. 보이는 화면은 줄어들었지만, 브라우저가 렌더링하고 있는 뷰포트는 그대로이다! (iOS 사파리에서는 주소창에 희미하게 블러 처리된 페이지가 보일 것이다) 이것은 앞서 말한 대로 모바일 웹브라우저는 렌더링의 효율을 위해 뷰포트를 유지하기 때문이다.

뷰포트에 보이는 대로 레이아웃 만들기

그렇다면 뷰포트에 보이는 대로, 화면에 꽉차는 레이아웃은 어떻게 만들 수 있을까?

MDN: VisualViewport 문서를 보면 현재 윈도우의 보이는 대로의 뷰포트를 얻어올 수 있는 API인 window.visualViewport 를 확인할 수 있다. 2019년 12월 현재 대부분의 모던 모바일 브라우저와 웹뷰에서 지원하는 API이므로, 충분히 사용할만한 기술이다. 뷰포트가 변화할 때마다 리사이즈 이벤트리스너를 통해 실제 레이아웃을 바꾸어주면 된다.

예시 코드

모바일 인앱 브라우저에서 보기: kidk.kr/visual-viewport-example/index.html