아이폰 safe-area-inset 적용 실패 사례와 해결
문제는 굉장히 단순했다. 아이폰의 하단 레벨이 원하던 CSS: 0px이 아닌 상대적인 bottom level을 읽지 못해 하단 탭바가 계속 밑으로 내려가는 현상이 발생했다. 그렇다보니 수동적으로 .css를 변경, 또는 동적으로 탭바가 생성된 이후에 렌더링이 되도록 설정을 해보아도 본질적인 해답이 아니다보니 5일이 넘도록 찾아 헤맸는데 아이폰 개발자가 아니다보니 다양한 방법으로 실패를 해보고 난 이후에 메타태그의 수정으로 간단하게 문제를 해결할 수 있었다.
State
- 정확한 문제는 처음 앱 진입시 문제없이 렌더링이 되어진다. 하지만 홈화면에서 다시 re-진입시 버그가 발생.
- 버그는 하단 탭바가 밑으로 끌어당겨지고, container가 감싸 주어야 할 area는 background-color: grey가 보인다.
- 또 하나의 이슈는 총 5개의 테스트플라이트+앱 중 2개만 해당 버그가 발생.
Device Screen Sizes and Orientations
알다시피 아이폰뿐 아니라 갤럭시나 샤오미 핸드폰 기종들은 고유의 Dimensions이 있어, 앱을 디자인할 때 모든 기종에 호환가능한 레이아웃을 만들어주는 게 우선이다. 특히 아이폰X에서부터는 notch라고 불리는 머머리가 탄생을 했는데, 이것때문에 적용된 개념이 Safe Area이다. 이전 기종과는 달리 디스플레이에서 상/하단의 라운드 영역을 포함하고 있기 때문에 안정적으로 콘텐츠를 노출시키려면 Safe Area를 가지고 있어야 한다.
아이폰X 이전에는 layout guides를 수동으로 설정해둘 수 있었지만, Xcode에서 네이티브 빌드 진행시 Use Safe Area Layout Guides를 체크로 적용가능하다. 나의 경우에는 Safe Area Layout이 적용이 안 된 상태로 앱이 올려졌고, 현재 네이티브를 수정할 수도 없는 상황이었기 때문에 다른 방식으로 접근하기로 한다.
아이폰 X 안전영역 대응 CSS 수정
가장 간단하게는 화면에 뿌려지는 렌더링을 단순 수정하는 것이다. 현재 설정은
bottom: 0px;
으로 하단 탭바 컨트롤러는 height: 64px; 으로 설정되었다.
그렇기 때문에 전체화면적용으로 메타태그와 env()속성을 적용시켜주면 될 것이라 생각했다.
1. index.html의 뷰포트 메타태그에서 viewport-fit=cover를 추가
<meta name='viewport' content='initial-scale=1, viewport-fit=cover'>
2. 아이폰 env()와 constant() 적용
/* iOS 11.0 버전 */
constant(safe-area-inset-top)
constant(safe-area-inset-bottom)
constant(safe-area-inset-left)
constant(safe-area-inset-right)
/* iOS 11.2 이상 */
env(safe-area-inset-top)
env(safe-area-inset-bottom)
env(safe-area-inset-left)
env(safe-area-inset-right)
결과는 실패. 이유는 1. 첫번째 진입시에 기존에 64px보다 훨씬 위로 뿌려주는 현상이 발생. 2. 두번째 re-진입시에도 완벽하게 대응되는 사이즈가 아니었다.
곰곰히 생각을 해보니 CSS로 환경을 맞춰주는 것은 근본적인 해결책이 아닌 것 같다.
테스트 환경에서만 작동하고 실서비스에서 또 어떤 문제가 일어날 지 모르기 때문에 다른 방법을 찾아본다.
외주개발자님께서 initTabbar()가 시작되는 home.js에서 함수가 실행될 때 jQuery로 CSS를 적용시켜보면 어떻겠냐고 알려주셨지만, 역시 근본적인 문제를 해결하진 못했다.
결국 내가 원하는 건 균일한 화면으로 적용을 시켜주는 것이기 때문에 '진짜 해결책'을 찾는 게 중요했다.
문제는 내가 모르는 것에서부터 시작한다.
전체 코드중 내가 모르는, 간과했던 코드를 찾아본다. '생각없이'썼던 코드에 해결책이 있다.
<meta name="viewport" content="width=device-width, minimal-ui, viewport-fit=cover">
2017년 8월 업데이트후에 생긴 속성으로 Safari iOS가 자동으로 패딩을 적용하기 때문에 생긴 속성이다.
처음에는 minimal-ui (iOS7의 주요 변경 사항으로 진정한 전체 화면 모드가 아닌 최소 ui 뷰포트 속성)이라고 생각했으나, viewport-fit=cover라 수상쩍었다.
<meta name="viewport" content="width=device-width, minimal-ui, viewport-fit=cover"> |
"viewport meta tag"는 애플이 사파리iOS상에서 디벨로퍼들이 뷰포트의 사이즈와 스케일을 컨트롤하게끔 도입한 개념으로 애플의 documentation 에 이와같은 개념에 대해 잘 정리해두었다.
Viewport basics
viewport-fit의 default value는 auto인데, 이때 default를 적용하고 싶지 않을 때 viewport-fit=cover를 쓴다. (대부분의 블로그글, 웹사이트에서 설명하고 있는 내용이다.) 예시에 cover를 적용시킨다면, 리로딩후에는 edge부터 edge까지 전체화면으로 펼쳐지는데, 생각해보니 이 cover라는 속성이 하단 탭바가 늘어지는 이유라고 생각이 들었다.
(사파리에서는 렌더링시 보여주어야할 내용이 필요하다면 자동으로 shrink을 해준다고 하여 shrink-to-fit=no라는 content도 있지만 어찌된 영문인지 적용이 안된것으로 보인다.)
그리고 cover이외에 들어갈 다른 속성들을 찾아보니
- contain: 뷰포트는 웹 콘텐트를 완벽히 적용시켜야한다. position이 fixed로 적용된 요소들은 iOS 11의 safe area안에서 모두 렌더링된다.
그리고 문제해결.
너무나 간단하고 예쁘게 해결되서 다행스러우면서도 황당하다. 사실 지금도 cover가 더 높은 개념의 viewport를 감싸준다고 생각이 드는데, 단순한 메타태그의 변화를 감지한 것인지 다시 한번 생각해봐야겠다.
'Front End' 카테고리의 다른 글
인터랙티브 웹 개발 제대로 시작하기-CSS 3D (0) | 2021.12.07 |
---|---|
인터랙티브 웹 개발 제대로 시작하기-CSS 변환과 애니메이션 (0) | 2021.12.05 |
Top 10 트렌딩 React.js 라이브러리 of 2021 (0) | 2021.11.28 |
<img> 태그와 background-img CSS 태그 (0) | 2021.10.21 |
[JavaScript] 구글맵 Google Map API (0) | 2021.08.18 |