---
title: "Safe Area"
description: "The safe area modifier and how it interacts with other views."
url: https://www.swiftuifieldguide.com/layout/safe-area
markdown_url: https://www.swiftuifieldguide.com/layout/safe-area.md
---
> Convenience Markdown export of the HTML page. Interactive samples, diagrams, and visualizations stay on the canonical page.
# The Safe Area

The safe area is the part of the screen that is visible to the user without being obstructed by system-provided controls such as the status bar, navigation bar, home indicator or tab bars. In the example below, the safe area is marked in green.

> Interactive example on HTML page: Advanced Example.

In the example above, we can see that the scroll view becomes exactly as large as the safe area, yet its content is still visible outside of the safe area. Put another way, we could say that the scroll view in the example above is exactly as large as the screen, but has its content inset to the size of the safe area. To the outside, however, the bounds of the scroll view are the bounds of the safe area. This way, when the user scrolls all the way to the top or bottom, the content is not obstructed.

When we select the second tab, we can see that the resizable image fills the safe area exactly, but does not extend beyond the safe area. Most views in SwiftUI behave like this, but we can also control this ourselves. In the third tab, we used a grid but made it ignore the safe area. It stretches behind the navigation bar and toolbar, all the way to the edges of the screen.

## Ignoring the Safe Area

In the example below, we have added two fake toolbars to the top and bottom of the screen using the `safeAreaInset` modifier. When we add the `ignoresSafeArea` modifier to our color, the view stretches beyond the safe area.

> Pretty-printed code from Color Example

```txt
Color.orange
    .padding(.horizontal)
    .ignoresSafeArea()
    .safeAreaInset(edge: .top) { MyToolbar() }
    .safeAreaInset(edge: .bottom) { MyToolbar() }
```

> Interactive example on HTML page: Color Example.

For more complicated hierarchies, it matters a lot where we apply the `ignoresSafeArea` modifier. In the example below, we have a vertical stack with two background colors. When we apply the modifier to the VStack, the entire stack stretches beyond the safe area. When we apply the modifier to the individual views, only the individual views stretch beyond the safe area. To see the difference, try enabling only the top bar or only the bottom bar and then toggling the placement of the modifier. We'll see that the stack still distributes the space evenly, but the individual views can then stretch beyond the safe area.

> Pretty-printed code from Simple Example

```txt
VStack {
    Color.yellow
        /* .ignoresSafeArea() */
    Color.orange
        /* .ignoresSafeArea() */
}
.padding(.horizontal)
.ignoresSafeArea()
.safeAreaInset(edge: .top, spacing: 0) {
    MyToolbar()
}
.safeAreaInset(edge: .bottom, spacing: 0) {
    MyToolbar()
}
```

> Interactive example on HTML page: Simple Example.

## Custom Insets

As we have seen above, we can add to the safe area using the `safeAreaInset` modifier. (As of iOS 17, we can also use [safeAreaPadding](https://developer.apple.com/documentation/swiftui/view/safeareapadding(_:)-5lh9p) to extend the safe area without providing a view). The safe area insets work like a stack: when we have an existing inset, additional modifiers append their size to the inset. In the example below, we can add multiple bottom bars to the screen, and the bottom safe area inset is their combined height.

> Pretty-printed code from Bottom Example

```txt
Color.orange
    .padding(.horizontal)
    .ignoresSafeArea()
    .safeAreaInset(edge: .bottom, spacing: 0) {
        MyToolbar()
    }
    .safeAreaInset(edge: .bottom, spacing: 0) {
        MyToolbar()
    }
```

> Interactive example on HTML page: Bottom Example.

Note that we might also want to use `ignoresSafeArea` within `safeAreaInset` views. For example, to show the bottom cart button behind the home indicator, we need to add `ignoresSafeArea` to exactly the right view. When we add it to the cart the text will be obscured, but if we add it to the background, we get the effect we want.

> Pretty-printed code from Shopping Cart Example

```swift
ProductPlaceholder()
    .safeAreaInset(edge: .top, spacing: 0) {
        MyToolbar()
    }
    .safeAreaInset(edge: .bottom, spacing: 0) {
        HStack(alignment: .firstTextBaseline) {
            ZStack {
                Circle()
                    .frame(width: 18, height: 18)
                Text("1")
                    .foregroundStyle(
                        Color.accentColor
                    )
            }
            Text("My Order")
            Spacer()
            Text("$19")
        }
        .foregroundStyle(.white)
        .padding(8)
        .frame(maxWidth: .infinity)
        .background {
            Color.accentColor
                .ignoresSafeArea()
        }
        /* .ignoresSafeArea() */
    }
```

> Interactive example on HTML page: Shopping Cart Example.

## Gotchas

When you use the [`background`](/layout/background) modifier, you might get the unexpected effect of a view stretching beyond the safe area. This happens because there are multiple variants of the background modifier. When we use the background modifier without a trailing closure and with no other parameters, the [background(_:ignoresSafeAreaEdges:)](https://developer.apple.com/documentation/swiftui/view/background(_:ignoressafeareaedges:)) variant is used, which takes a `ShapeStyle` instead of a `View` and has a default value of `all` for the edges. The Swift compiler chooses this overload because the type we provide (`Color`) is a more specific match than the other overloads. We can see the difference in the following example:

> Pretty-printed code from Background Example

```swift
Text("Hello, world.")
    .font(.title)
    .foregroundStyle(.white)
    .frame(maxWidth: .infinity,
           maxHeight: .infinity)
    .background(Color.purple)
    /* .background { Color.purple } */
```

> Interactive example on HTML page: Background Example.

## Geometry Reader

When you need programmatic access to the values of the safe area, you can use a [geometry reader](/layout/geometry-reader). In the example below, we visualized the size of the geometry reader using a blue background. When the geometry reader is not ignoring the safe area, the proxy's `safeAreaInsets` property contains non-zero values. When you ignore the safe area, the geometry reader fills the entire screen but the insets will be zero.

> Pretty-printed code from Geometry Reader Example

```swift
GeometryReader { proxy in
    VStack {
        Text(
            "\(proxy.size.width) x \(proxy.size.height)"
        )
        Text(
            "top: \(proxy.safeAreaInsets.top), bottom: \(proxy.safeAreaInsets.bottom)"
        )
    }
    .frame(width: proxy.size.width,
           height: proxy.size.height)
    .font(.caption)
}
.foregroundStyle(.white)
.background(Color.accentColor)
/* .ignoresSafeArea() */
.safeAreaInset(edge: .top, spacing: 0) {
    MyToolbar()
}
.safeAreaInset(edge: .bottom, spacing: 0) {
    MyToolbar()
}
```

> Interactive example on HTML page: Geometry Reader Example.

You can also use a geometry reader to provide a [visualization of the safe area](https://chris.eidhof.nl/post/visualize-swiftui-safe-area/) in your own code.

## More Resources {#references}

> Related resource: In this article, Fatbobman shows a number of both simple and advanced examples of how to work with the safe area in SwiftUI. (https://fatbobman.com/en/posts/safearea/)

> Related resource: In SwiftUI's official documentation we can see how to add a background to a view, and how to use the safe area insets to make sure the background is visible even when the keyboard shows. (https://developer.apple.com/documentation/swiftui/adding-a-background-to-your-view)

> Related resource: The Human Interface Guidelines contains an article about layout that talks about the safe area from a design perspective. (https://developer.apple.com/design/human-interface-guidelines/layout)
