SASS safe 함수

아이폰X 노치영역 대응 최적화에 대해 적용 범위가 점점 늘어가면서 타이핑이 너무 힘들어지는 어려움이 있어서 SASS 함수를 만들었습니다.

safe 함수는 영역 방향과 값을 전달해서 env(safe-area-inset-*)이 적용된 코드를 얻을 수 있습니다. 음수값으로 사용도 가능합니다. 나중에 함수가 수정되면 여기에 업데이트 하겠습니다.

// 노치 대응 기기 안전영역 환경변수 : safe-area

// 테스트용 safe area 변수 (값이 0일때는 0% 또는 0px 사용)
// $safeAreaMap: ("top": 44px, "right": 0%, "bottom": 34px, "left": 0%);
$safeAreaMap: ("top": env(safe-area-inset-top), "right": env(safe-area-inset-right), "bottom": env(safe-area-inset-bottom), "left": env(safe-area-inset-left));

$safe-top: map-get($safeAreaMap,"top");
$safe-right: map-get($safeAreaMap,"right");
$safe-bottom: map-get($safeAreaMap,"bottom");
$safe-left: map-get($safeAreaMap,"left");

/**
 * safe-area-inset 처리
 * $dir - 방향(all, top, right, bottom, left, 생략가능)
 * $value - 더해질 값(생략가능)
 */
@function safe($dir: all, $value: 0) {
	@if ($dir == all) {
		@if ($value > 0) {
			@return calc(#{$value} + #{map-get($safeAreaMap,"top")}) calc(#{$value} + #{map-get($safeAreaMap,"right")}) calc(#{$value} + #{map-get($safeAreaMap,"bottom")}) calc(#{$value} + #{map-get($safeAreaMap,"left")});
		}
		@else if ($value < 0) {
			@return calc((#{-$value} + #{map-get($safeAreaMap,"top")}) * -1) calc((#{-$value} + #{map-get($safeAreaMap,"right")}) * -1) calc((#{-$value} + #{map-get($safeAreaMap,"bottom")}) * -1) calc((#{-$value} + #{map-get($safeAreaMap,"left")}) * -1);
		}
		@else {
			@return map-get($safeAreaMap,"top") map-get($safeAreaMap,"right") map-get($safeAreaMap,"bottom") map-get($safeAreaMap,"left");
		}
	}
	@else {
		@if ($value > 0) {
			@return calc(#{$value} + #{map-get($safeAreaMap,$dir)});
		}
		@else if ($value < 0) {
			@return calc((#{-$value} + #{map-get($safeAreaMap,$dir)}) * -1);
		}
		@else {
			@return map-get($safeAreaMap,$dir);
		}
	}
}

이렇게 함수를 정의해놓고,
코드에서 아래와 같이 사용합니다.

// 방향과 값
.btn {
	position: absolute;
	bottom: 0;
	bottom: safe(bottom);
	left: 10px;
	left: safe(left,10px);
}
// bottom: 0;
// bottom: env(safe-area-inset-bottom);
// left: 10px;
// left: calc(10px + env(safe-area-inset-left);

// 음수 마진과 양쪽 패딩
.box {
	margin: 0 -15px;
	margin: 0 safe(left,-15px);
	padding: 20px 15px;
	padding: 20px safe(left,15px);
	background: #f5f5f5;
}
// margin: 0 -15px;
// margin: 0 calc((15px + env(safe-area-inset-left)) * -1);
// padding: 20px 15px;
// padding: 20px calc(15px + env(safe-area-inset-left));

// 상하좌우 마진 / 패딩
.box2 {
	margin: 0;
	margin: safe();
	padding: 15px;
	padding: safe(all,15px);
}
// margin: 0;
// margin: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
// padding: 15px;
// padding: calc(15px + env(safe-area-inset-top)) calc(15px + env(safe-area-inset-right)) calc(15px + env(safe-area-inset-bottom)) calc(15px + env(safe-area-inset-left));