Elevation은 z축(화면에 수직)을 따라 요소의 높이를 정의하는 Material Design의 기본 개념입니다. Elevation은 dp로 측정되며 요소가 드리우는 그림자의 크기와 흐림에 직접적인 영향을 미칩니다. Elevation이 높을수록 요소가 사용자에게 더 가깝게 느껴지고 시각적 무게가 더 눈에 띕니다. Material Design 3(Google, 2026)에 따르면 카드의 표준 elevation은 1dp, FloatingActionButton은 6dp, 대화상자는 24dp입니다. 그림자 구현에 대한 자세한 내용은 UI 그림자에 대한 문서를 참조하세요.
핵심 사항
Elevation은 Material Design(Google I/O 2014)에서 도입된 메트릭으로, z축을 따른 요소의 위치를 나타냅니다. x 및 y(화면의 2차원 평면)와 달리 z는 평면 위의 높이입니다. Elevation은 dp(밀도 독립 픽셀)로 표현되며 두 가지 시각적 효과를 결정합니다: elevation이 증가함에 따라 더 커지고 흐려지는 그림자와 그리기 순서(높은 elevation의 요소가 낮은 elevation의 요소 위에 그려짐)입니다.
물리적 비유: 테이블 위의 종이 더미를 상상해보세요. 더미가 높을수록 맨 위 종이의 그림자가 길어집니다. Material Design의 Elevation도 정확히 같은 방식으로 작동합니다 — 각 요소는 특정 높이에 있는 “디지털 시트”입니다. 사용자가 요소와 상호작용할 때(버튼 누름, 카드 들어올림) elevation이 일시적으로 증가합니다 — 이를 “상호작용 elevation”이라고 합니다.
Material Design Guidelines(Google, 2026)에 따르면 elevation을 적절히 사용하면 인터페이스 스캔 가능성이 35% 향상됩니다: 사용자가 대화형 요소를 더 빨리 찾을 수 있습니다. 평평한 콘텐츠 위로 “돌출”되기 때문입니다. 그러나 과도한 elevation 레벨(4개 초과)은 이 효과를 감소시킵니다 — 모든 것이 떠 있으면 아무것도 중요해 보이지 않습니다.
Android에서 elevation은 API 21(Android 5.0 Lollipop)부터 View의 내장 속성으로 구현되었습니다. View.elevation은 픽셀(px) 단위의 기본 높이를 설정하고 View.translationZ는 애니메이션을 위한 추가 오프셋을 제공합니다(예: 누를 때). 총 시각적 높이 = elevation + translationZ. 두 속성 모두 ViewPropertyAnimator 또는 ObjectAnimator를 통한 애니메이션을 지원합니다.
<!-- XML: elevation 및 translationZ -->
<Button
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="4dp"
android:translationZ="2dp"
android:stateListAnimator="@anim/button_elevation"
android:text="Elevation이 있는 버튼" />
StateListAnimator — View 상태(누름, 포커스, 활성)에 따라 elevation과 translationZ를 애니메이션화하는 XML 리소스입니다. 예를 들어 버튼을 누르면 elevation이 2dp에서 8dp로 증가하여 들어올림 효과를 만듭니다. StateListAnimator는 모든 View 속성에 대해 ObjectAnimator를 통한 애니메이션을 지원합니다.
// Kotlin: 프로그래매틱 elevation 설정
import android.animation.ObjectAnimator
import android.view.View
val myButton: View = findViewById(R.id.myButton)
myButton.elevation = 4f // px 단위 기본 높이
// 누를 때 elevation 애니메이션
val animator = ObjectAnimator.ofFloat(
myButton,
"translationZ",
0f,
8f
).apply {
duration = 150
repeatMode = ValueAnimator.REVERSE
repeatCount = 1
}
OutlineProvider — elevation 그림자를 올바르게 렌더링하기 위한 핵심 구성 요소입니다. 기본적으로 Android는 ViewOutlineProvider.BACKGROUND를 사용하여 배경 drawable을 기반으로 윤곽선을 만듭니다. 둥근 모서리가 있는 View(shape drawable을 통해)의 경우 사용자 정의 OutlineProvider를 설정해야 합니다. 그렇지 않으면 그림자가 직사각형이 됩니다. Material 구성 요소(CardView, MaterialButton)는 OutlineProvider를 자동으로 관리합니다.
Material Design 3(Material You)는 Material Design 2와 비교하여 elevation 시스템을 개정했습니다. 12개의 고정 레벨(Material 2) 대신 M3는 5가지 기본 톤을 제공하며 각각 특정 elevation 레벨에 해당합니다. 또한 M3는 Android 12+에서 “컬러 그림자” 개념을 도입했습니다: 그림자가 검은 회색이 아닌 테마의 강조 색상으로 착색될 수 있습니다.
| 레벨 | Elevation | 용도 | 그림자(밝은 테마) |
|---|---|---|---|
| 레벨 0 | 0 dp | 배경, Surface 컨테이너 | 그림자 없음 |
| 레벨 1 | 1 dp | 카드, ListItem, 메뉴 | 0.05 불투명도, 2px 흐림 |
| 레벨 2 | 3 dp | 검색창, 하단 탐색 | 0.08 불투명도, 4px 흐림 |
| 레벨 3 | 6 dp | FAB, FloatingActionButton | 0.11 불투명도, 8px 흐림 |
| 레벨 4 | 8 dp | Snackbar, 바텀 시트 | 0.12 불투명도, 12px 흐림 |
| 레벨 5 | 12 dp | 탐색 서랍, 대화상자 | 0.14 불투명도, 16px 흐림 |
| 레벨 6 | 24 dp | 모달 대화상자, 팝업 메뉴 | 0.15 불투명도, 24px 흐림 |
상호작용 elevation — 사용자가 요소와 상호작용하는 동안 elevation이 일시적으로 증가하는 것입니다. Material Design 3에서 대화형 요소(버튼, 카드)는 누를 때(pressed 상태) 또는 포커스할 때(focused 상태) 기본 elevation에 +1–2dp를 얻습니다. FloatingActionButton의 경우 상호작용 elevation은 +6dp입니다. 자연스러운 촉각 반응을 위해 상태 간 전환 애니메이션은 150–200ms 동안 지속되어야 합니다.
Jetpack Compose는 내장 elevation 매개변수가 있는 Card 및 Surface 구성 요소를 통해 elevation을 지원합니다. View 시스템과 달리 Compose는 자체 렌더링 엔진을 통해 그림자를 렌더링하므로 모든 Android 버전(API 21+)에서 일관된 동작을 보장합니다. Modifier.shadow()는 모든 composable에 그림자를 추가하기 위한 저수준 수정자입니다.
// Jetpack Compose: Surface 및 Card를 통한 elevation
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Surface
Card(
elevation = CardDefaults.cardElevation(
defaultElevation = 4.dp,
pressedElevation = 8.dp,
focusedElevation = 6.dp
),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surface
)
) {
Text("Elevation 제어 카드")
}
// 사용자 정의 모양을 위한 Modifier.shadow
Surface(
modifier = Modifier
.shadow(elevation = 6.dp, shape = RoundedCornerShape(16.dp))
.clickable { /* 동작 */ },
shape = RoundedCornerShape(16.dp),
color = MaterialTheme.colorScheme.surface
) { Text("그림자가 있는 표면") }
Elevation 애니메이션은 Compose에서 animateFloatAsState 또는 Animatable을 통해 구현됩니다. Elevation이 변경되면 Compose가 자동으로 그림자를 애니메이션화합니다. 대화형 요소의 경우 M3 InteractionSource를 animateElevation과 함께 사용하여 elevation이 누름, 포커스 및 드래그에 반응하도록 합니다. Compose 1.2+의 Material 3는 컬러 그림자(테마의 primary Container 색상으로 착색된 그림자)를 지원합니다.
iOS에는 Material Design의 elevation에 대한 내장 유사체가 없습니다. Apple의 Human Interface Guidelines는 그림자 관리에 z좌표를 사용하지 않습니다 — 대신 개발자가 CALayer.shadow*를 통해 수동으로 그림자를 구성합니다. 그러나 그림자와 깊이를 통한 시각적 계층 구조의 개념은 iOS에도 존재합니다: 모달 프레젠테이션, UIAlertController, UIPopoverPresentationController — 모두 배경과 구분하기 위해 그림자를 사용합니다.
iOS에서 elevation을 시뮬레이션하려면 개발자가 shadowOpacity + shadowRadius + shadowOffset의 조합을 사용합니다. 필요한 “높이”가 높을수록 흐림 반경과 그림자 오프셋이 커집니다. SwiftUI에서는 매개변수와 함께 .shadow() 수정자를 통해 그림자가 설정됩니다. iOS에서 Material과 유사한 동작을 위해 Google의 Material Components for iOS (MDC)와 같은 라이브러리가 있습니다.
// iOS: CALayer를 통한 elevation 시뮬레이션
import UIKit
extension UIView {
func applyElevation(level: Int) {
let elevationMap: [Int: (CGFloat, CGFloat, CGFloat)] = [
1: (0.05, 1, 2),
2: (0.08, 2, 4),
3: (0.11, 4, 8),
4: (0.12, 6, 12),
5: (0.14, 8, 16),
6: (0.15, 12, 24)
]
let (opacity, offset, radius) = elevationMap[level] ?? (0.08, 2, 4)
layer.shadowColor = UIColor.black.cgColor
layer.shadowOpacity = Float(opacity)
layer.shadowOffset = CGSize(width: 0, height: offset)
layer.shadowRadius = radius
layer.shouldRasterize = true
layer.rasterizationScale = UIScreen.main.scale
}
}
// 사용법
cardView.applyElevation(level: 3) // 6dp에 해당
Material Components for iOS (MDC-iOS) — Material Design elevation을 iOS로 포팅하는 Google 라이브러리입니다. MDC-iOS는 미리 정의된 값이 있는 MDCShadowElevation 클래스, 그림자 렌더링을 위한 MDCShadowLayer 및 올바른 elevation이 있는 Material 카드를 위한 MDCCard를 제공합니다. MDC-iOS는 상태 저장 그림자 속성을 통해 누를 때 elevation 애니메이션을 지원합니다.
자주 묻는 질문
Elevation — z평면에서 요소의 기본 높이(XML 또는 코드에서 설정). translationZ — 애니메이션을 위한 동적 오프셋(예: 누를 때). 시각적 높이 = elevation + translationZ. elevation은 ViewPropertyAnimator를 통해, translationZ는 ObjectAnimator를 통해 애니메이션화됩니다. 일시적인 높이 변경에는 translationZ를, 영구적인 변경에는 elevation을 사용하세요.
Material Design 3는 디자이너와 개발자의 인지 부하를 줄이기 위해 elevation 시스템을 12레벨에서 7레벨로 간소화했습니다. 정확한 값(2dp, 4dp, 8dp) 대신 M3는 미리 정의된 그림자 매개변수가 있는 톤(레벨 0–6)을 사용합니다. Android 12+에서는 앱 테마에 맞게 조정되는 컬러 그림자 지원이 추가되었습니다.
Elevation 자체는 성능에 영향을 미치지 않습니다. 그림자는 하드웨어(GPU)에 의해 렌더링되기 때문입니다. 그러나 elevation의 빈번한 변경(애니메이션 중 매 프레임)은 View 및 인접 영역의 다시 그리기를 유발할 수 있습니다. 애니메이션의 경우 elevation을 변경하는 대신 translationZ를 사용하세요. translationZ는 빈번한 변경에 최적화되어 있습니다. 20개 이상의 elevation 요소가 있는 복잡한 화면의 경우 view.setLayerType(View.LAYER_TYPE_HARDWARE, null)을 활성화하세요.
Android에서 elevation은 항상 요소를 배경 위로 들어올리고 그리기 순서(z-order)를 변경합니다. z-order를 변경하지 않고 그림자만 필요한 경우 CardView에서 cardUseCompatPadding을 사용하거나 onDraw()에서 Paint.setShadowLayer()를 통한 사용자 정의 그림자 렌더링을 사용하세요. Jetpack Compose에서는 Modifier.graphicsLayer { shadowElevation = 4f }를 사용하세요.
Material Design 구성 요소에는 고정된 elevation 값이 있습니다: FloatingActionButton — 6dp(누를 때 12dp), CardView — 1–8dp(구성 가능), BottomNavigationView — 8dp, Toolbar — 4dp, Snackbar — 6dp, Dialog — 24dp. Material Components Library의 MaterialButton은 2dp의 elevation을 가지며 누를 때 8dp로 상승합니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.