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

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

JP
이중표Frontend Engineer

3년차 프론트엔드 개발자. Next.js, React, TypeScript 기반 웹 애플리케이션 개발 전문. 대규모 트래픽 환경에서 SSR·ISR 렌더링 전략 설계 경험.

이력서 보기