CSS 아이폰 안전영역(safe area) 대응 : 아이폰 노치 대응

Eddy·2022년 12월 19일
4

CSS

목록 보기
6/8

1. 안전영역(Safe Area)이란?

Safe Area는 원래 TV에서 처음 도입된 개념입니다.
TV 해상도 비율이 다양해지면서 영상에서 타이틀, 자막 등이 필수 콘텐츠의 노출을 보장할 수 있는 영역입니다.
보통 오래된 TV 해상도가 가진 4:3 비율 기준으로 타이틀, 자막 등이 모두 노출되게 작업을 했습니다.

TV Safe Area (http://www.indefilms.net/html/title_safe_area.html)

2. 왜 아이폰X는 Safe Area가 필요할까요? (X 이후 기종 포함)

아이폰8 이하 기종과 달리 아이폰X의 디스플레이 영역은 상/하단 라운드 영역을 포함하고 있습니다.
추가적으로 상단 영역은 카메라, 스피커 등의 센서가 있는 노치(notch)가 존재하여 콘텐츠가 제대로 노출될 수 없습니다.
그래서 아이폰X은 안정적으로 콘텐츠가 보일 수 있는 Safe Area를 가지고 있습니다.

아이폰8, 아이폰X 화면 영역 비교 (http://blog.rightbrain.co.kr/?p=8499)

iPhone Xs(v12.3.1) Safe Area

3. Safe Area 문제점

기본적으로 아이폰X 화면 상단은 앱 또는 브라우저가 가지고 있는 내비게이션 고정 영역이 있으므로 Safe Area를 크게 신경 쓸 필요는 없습니다.
하지만 좌/우/하단 영역의 경우 아이폰X과 그 외 디바이스에서 보이는 게 다를 수 있습니다.
이해를 돕기 위해 테스트 페이지를 만들어 비교해 보았습니다.

테스트 환경 iPhone 6(v12.4.1) / iPhone Xs(v12.3.1)

위 그림에서 살펴보면 크게 2가지 문제점이 있습니다.

Safe Area 밖의 margin 영역(스타일 적용 못함) 노출
화면 하단 홈 인디케이터 영역과 레이아웃 겹침 현상 발생
제가 진행한 프로젝트는 위 디자인 이슈가 발생하여 Safe Area 설정을 변경해야 했습니다.

4-1. 아이폰X : 전체 화면 적용

전체 화면 설정 방법은 매우 간단합니다.
뷰포트 메타태그에서 viewport-fit=cover 를 추가합니다.
참고로 viewport-fit 기본값은 auto 입니다.

<meta name='viewport' content='initial-scale=1, viewport-fit=cover'>

iPhone Xs(v12.3.1) viewport-fit=cover 적용

4-2.아이폰X : env() 속성 적용

전체 화면을 적용 시 아이폰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)

적용 예시 1

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);
}

적용 예시 2

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 를 제외한 나머지 값만 적용됩니다.

5.아이폰X의 safe-area-inset margin

마지막으로 위 예시 화면을 살펴보면 세로 모드와 가로 모드일 경우 하단 safe-area-inset 의 margin 이 다른 것을 확인할 수 있습니다.
각 모드에 따른 safe-area-inset 의 margin 이 궁금해집니다.
아래 테스트 화면 참고하세요.

iPhone Xs(v12.3.1) 가로/세로 모드 safe-area-inset margin

1개의 댓글

comment-user-thumbnail
2024년 2월 14일

env() 는 아이폰X에서만 동작 하고 그 외 디바이스에는 영향을 주지 않는다고 하셨는데요, 크롬 브라우저도 동작하는데 왜 그런 것일까요?

답글 달기