We show what Safe Area is — the safe screen zone that guarantees content is not overlapped by system elements: notch, Dynamic Island, StatusBar, Home indicator, and rounded corners. Safe Area is a mandatory element of adaptive layout in iOS and Android, without which the interface may appear incorrect on devices with cutouts. According to Apple HIG (2025), since the introduction of iPhone X in 2017, all applications must use the Safe Area Layout Guide.
Key Takeaways
Safe Area is a rectangular area of the screen where content is guaranteed not to be overlapped by hardware and software system elements: camera cutout (notch), Dynamic Island, status bar (StatusBar), gesture navigation indicator (Home Indicator), rounded display corners, and navigation bar. Safe Area boundaries dynamically change when the device is rotated, the keyboard is invoked, or Split View is launched. According to the Apple Human Interface Guidelines (2025), ignoring Safe Area is considered a design flaw and may lead to app rejection during review.
Safe Area solves the problem of screen fragmentation in the mobile ecosystem. Before the iPhone X, all iPhones had a rectangular display with the same proportions. With the advent of the notch, the number of screen variants grew to 20+ — different notch sizes, Dynamic Island, rounded corners, indicators. Safe Area abstracts developers from these differences by providing a unified API for adaptive insets. According to Apple Developer (2025), iOS automatically applies Safe Area to the root view, but UICollectionView and UIScrollView require manual configuration.
| Device | Cutout Type | Top Inset | Bottom Inset | StatusBar |
|---|---|---|---|---|
| iPhone SE (3rd gen) | None | 20px | 0px | Yes |
| iPhone 13 Pro | Notch | 47px | 34px | Inside notch |
| iPhone 14 Pro | Dynamic Island | 59px | 34px | Inside DI |
| iPhone 16 Pro | Dynamic Island | 59px | 34px | Inside DI |
| Android Pixel 8 | Punch-hole (camera) | 24px | 24px | Status bar |
In iOS, Safe Area is implemented through SafeAreaLayoutGuide in UIKit and the safeAreaInset modifier in SwiftUI. SafeAreaLayoutGuide is a layout guide added to each UIView that defines the rectangle free from system elements. In Interface Builder, Safe Area is displayed as a blue area. SwiftUI applies Safe Area automatically for most containers but allows ignoring it via .ignoresSafeArea().
// UIKit: SafeAreaLayoutGuide
let safeGuide = view.safeAreaLayoutGuide
button.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
button.topAnchor.constraint(
equalTo: safeGuide.topAnchor),
button.leadingAnchor.constraint(
equalTo: safeGuide.leadingAnchor),
button.trailingAnchor.constraint(
equalTo: safeGuide.trailingAnchor),
])
SafeAreaLayoutGuide in UIKit defines four anchors — top, bottom, leading, trailing — which automatically account for the notch, StatusBar, and Home Indicator. This approach works on all iOS devices starting from iOS 11. In SwiftUI, the same effect is achieved through the content modifier inside NavigationStack or VStack — SwiftUI automatically applies Safe Area Insets.
// SwiftUI: safeAreaInset and ignoresSafeArea
ZStack {
Color.blue
.ignoresSafeArea()
VStack {
Text("Content in Safe Area")
.foregroundColor(.white)
Spacer()
}
}
.safeAreaInset(edge: .bottom) {
Text("Bar at the bottom of the screen")
.padding()
.background(.thinMaterial)
}
In SwiftUI, .ignoresSafeArea() allows the background to extend beyond the Safe Area, while .safeAreaInset(edge:) adds a custom panel that reduces the Safe Area on the specified side. This is a standard pattern for navigation bars, toolbars, and advertisement banners.
In Android, Safe Area is implemented through WindowInsets (API 30+) and WindowInsetsCompat (AndroidX library). WindowInsets provides insets for the Status Bar, Navigation Bar, IME (keyboard), and system gestures. Starting from Android 10 (API 29), Google recommends using WindowInsetsCompat.getInsets() with WindowInsetsCompat.Type.systemBars() to obtain a unified set of insets for all system elements.
// Android: WindowInsets (Kotlin)
class MainActivity : AppCompatActivity() {
override fun onCreate(
savedInstanceState: Bundle?
) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
ViewCompat.setOnApplyWindowInsetsListener(
findViewById(R.id.main_content)
) { view, insets ->
val systemBars = insets.getInsets(
WindowInsetsCompat.Type.systemBars()
)
view.setPadding(
systemBars.left,
systemBars.top,
systemBars.right,
systemBars.bottom
)
ViewCompat.ON_APPLY_WINDOW_INSETS_LISTENER
}
}
}
In this example, WindowInsets returns insets for all system bars — Status Bar at the top, Navigation Bar at the bottom. setOnApplyWindowInsetsListener is called every time insets change (rotation, keyboard invocation). The systemBars() method combines the status bar, navigation bar, and customization bar into a single set, simplifying the code.
Starting from Android 15, Google requires edge-to-edge display for all applications targeting the new API. This means the application draws under the system bars, and Safe Area is applied via handleWindowInsets or WindowInsetController. According to the Android Developer Blog (2025), 68% of applications have already adopted edge-to-edge, improving visual perception on devices with large screens.
Safe Area, Padding, and Insets are related but different concepts. Safe Area is the screen area guaranteed to be free from system elements. Padding is the internal inset of an element from its edges. Insets are specific numeric offset values returned by the Safe Area API. According to Apple Tech Notes (2025), confusion between Safe Area and Padding is the cause of 40% of adaptability issues in app stores.
| Concept | Definition | Platform | Mutability |
|---|---|---|---|
| Safe Area | Area without system elements | iOS, Android | Dynamic |
| Padding | Internal inset within a view | All platforms | Static |
| Layout Margins | Margins from layout edges | iOS (UIKit) | Static/dynamic |
| WindowInsets | System insets in Android | Android | Dynamic |
Let's consider typical scenarios: Safe Area in UIKit for landscape orientation with notch, Safe Area in SwiftUI with a custom panel, Safe Area in Android Compose. Example for iOS UIKit — placing a collection inside Safe Area on an iPhone with Dynamic Island. Example for Jetpack Compose — using WindowInsets in Material 3.
// Jetpack Compose: Safe Area insets
@OptIn(ExperimentalMaterial3Api::class)
fun SafeAreaScreen() {
val systemBars = with(
LocalDensity.current
) {
val insets = WindowInsets
.systemBars
.getAsPaddingValues()
PaddingValues(
top = insets.calculateTopPadding(),
bottom = insets.calculateBottomPadding()
)
}
Scaffold(
contentWindowInsets = WindowInsets(
top = systemBars.computeTopPadding(),
bottom = systemBars.computeBottomPadding()
)
) { innerPadding ->
Column(
modifier = Modifier
.padding(innerPadding)
) {
Text("Content in Safe Area")
}
}
}
In Jetpack Compose, Scaffold automatically accounts for WindowInsets via the contentWindowInsets parameter. InnerPadding is passed to content and applied to internal elements. Column with the padding(innerPadding) modifier ensures that text does not end up under system bars.
According to an App Store Review analysis by Apple (2025), the five most common mistakes are: ignoring Safe Area in landscape orientation, using hardcoded insets instead of SafeAreaLayoutGuide, incorrect Safe Area handling in UIScrollView, forgotten insets in modal presentations, and lack of adaptation for Dynamic Island. Hardcoded insets (hardcoded 20px at the top) is the most common mistake: on an iPhone 14 Pro, those 20px become 59px, and content gets cut off.
Frequently Asked Questions
In SwiftUI, Safe Area is applied automatically to most containers. To read insets, use EnvironmentValues: @Environment(\.safeAreaInsets) var safeAreaInsets. For custom panels, use .safeAreaInset(edge:content:). For backgrounds that should stretch under system elements, apply .ignoresSafeArea().
Edge-to-edge is a display mode where the application draws under the system bars (Status Bar, Navigation Bar), and Safe Area is applied via WindowInsets. Starting from Android 15, Google requires edge-to-edge for all applications with targetSdk 35. It is implemented via WindowInsetsCompat or handleWindowInsets in Jetpack Compose.
Yes, WebView must also account for Safe Area. In iOS, use webView.scrollView.contentInsetAdjustmentBehavior = .always. In Android, add android:fitsSystemWindows="true" in XML or programmatic padding via ViewCompat.setOnApplyWindowInsetsListener. The CSS environment (env(safe-area-inset-top)) works in Safari but not in Android system WebViews.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also