Safe Area는 원래 TV에서 처음 도입된 개념입니다.
TV 해상도 비율이 다양해지면서 영상에서 타이틀, 자막 등이 필수 콘텐츠의 노출을 보장할 수 있는 영역입니다.
보통 오래된 TV 해상도가 가진 4:3 비율 기준으로 타이틀, 자막 등이 모두 노출되게 작업을 했습니다.
TV Safe Area (http://www.indefilms.net/html/title_safe_area.html)
아이폰8 이하 기종과 달리 아이폰X의 디스플레이 영역은 상/하단 라운드 영역을 포함하고 있습니다.
추가적으로 상단 영역은 카메라, 스피커 등의 센서가 있는 노치(notch)가 존재하여 콘텐츠가 제대로 노출될 수 없습니다.
그래서 아이폰X은 안정적으로 콘텐츠가 보일 수 있는 Safe Area를 가지고 있습니다.
아이폰8, 아이폰X 화면 영역 비교 (http://blog.rightbrain.co.kr/?p=8499)
iPhone Xs(v12.3.1) Safe Area
기본적으로 아이폰X 화면 상단은 앱 또는 브라우저가 가지고 있는 내비게이션 고정 영역이 있으므로 Safe Area를 크게 신경 쓸 필요는 없습니다.
하지만 좌/우/하단 영역의 경우 아이폰X과 그 외 디바이스에서 보이는 게 다를 수 있습니다.
이해를 돕기 위해 테스트 페이지를 만들어 비교해 보았습니다.
테스트 환경 iPhone 6(v12.4.1) / iPhone Xs(v12.3.1)
위 그림에서 살펴보면 크게 2가지 문제점이 있습니다.
Safe Area 밖의 margin 영역(스타일 적용 못함) 노출
화면 하단 홈 인디케이터 영역과 레이아웃 겹침 현상 발생
제가 진행한 프로젝트는 위 디자인 이슈가 발생하여 Safe Area 설정을 변경해야 했습니다.
전체 화면 설정 방법은 매우 간단합니다.
뷰포트 메타태그에서 viewport-fit=cover 를 추가합니다.
참고로 viewport-fit 기본값은 auto 입니다.
<meta name='viewport' content='initial-scale=1, viewport-fit=cover'>
iPhone Xs(v12.3.1) viewport-fit=cover 적용
전체 화면을 적용 시 아이폰X의 노치 영역과 하단 인디케이터 영역까지 모두 사용하므로 콘텐츠가 잘리거나 겹쳐 보이는 문제점이 발생할 수 있습니다.
그래서 아이폰X에서 사용 가능한 CSS 속성인 env() 를 제공하고 있으며 4개의 변수 적용이 가능합니다.
참고로 env() 는 아이폰X에서만 동작하므로 그 외 디바이스에는 영향을 주지 않습니다.
(* iOS 11에서 제공하는 동일한 속성인 constant() 가 11.2 버전부터는 제거되고, env() 로 대체되었기 때문에 하위 버전 대응이 필요하다면 constant() 도 같이 적용해주어야 합니다.)
// iOS 11.0 버전
constant(safe-area-inset-top)
constant(safe-area-inset-right)
constant(safe-area-inset-bottom)
constant(safe-area-inset-left)
// iOS 11.2 이상
env(safe-area-inset-top)
env(safe-area-inset-right)
env(safe-area-inset-bottom)
env(safe-area-inset-left)
위 속성만 넣어도 기본 padding 값이 있어서 늘어납니다.
값을 더 추가하면 기본값 + 더한값 표현 됩니다.
env() 지원 범위 (https://caniuse.com/#search=env)
iPhone Xs(v12.3.1) 세로 모드
.btn {
padding: 15px 0 calc(constant(safe-area-inset-bottom) + 15px);
padding: 15px 0 calc(env(safe-area-inset-bottom) + 15px);
}
iPhone Xs(v12.3.1) 가로 모드
.wrap {
padding-right:constant(safe-area-inset-right);
padding-left:constant(safe-area-inset-left);
padding-right:env(safe-area-inset-right);
padding-left:env(safe-area-inset-left);
}
.btn {
padding: 15px 0 calc(constant(safe-area-inset-bottom) + 15px);
padding: 15px 0 calc(env(safe-area-inset-bottom) + 15px);
}
calc() 를 이용하면 아이폰X 이외 디바이스는 safe-area-inset 를 제외한 나머지 값만 적용됩니다.
마지막으로 위 예시 화면을 살펴보면 세로 모드와 가로 모드일 경우 하단 safe-area-inset 의 margin 이 다른 것을 확인할 수 있습니다.
각 모드에 따른 safe-area-inset 의 margin 이 궁금해집니다.
아래 테스트 화면 참고하세요.
iPhone Xs(v12.3.1) 가로/세로 모드 safe-area-inset margin
env() 는 아이폰X에서만 동작 하고 그 외 디바이스에는 영향을 주지 않는다고 하셨는데요, 크롬 브라우저도 동작하는데 왜 그런 것일까요?