---
title: "ZStack"
description: "ZStacks layer views on top of each other."
url: https://www.swiftuifieldguide.com/layout/zstack
markdown_url: https://www.swiftuifieldguide.com/layout/zstack.md
---
> Convenience Markdown export of the HTML page. Interactive samples, diagrams, and visualizations stay on the canonical page.
# ZStack

A ZStack is a container that layers its views on top of each other. Unlike an [overlay](/layout/overlay) or [background](/layout/background), the views in a ZStack have sizes that are independent of each other. The first child of the ZStack is at the bottom, and the last view is at the top. The ZStack takes its proposed size and proposes that same size to each of its children. Once all children have their sizes, they are [aligned](/layout/alignment). Here's a simple example:

> Pretty-printed code from ZStack Simple

```swift
ZStack {
    Color.yellow
    Circle()
        .fill(.orange)
    Text("Hello")
        .foregroundStyle(.black)
}
```

> Interactive example on HTML page: ZStack Simple.

The reported size of the ZStack is the union of all the frames of the children. In most cases, this means that the ZStack will be as large as the largest child. However, the following example shows how the ZStack combines the frames of both views:

> Pretty-printed code from ZStack Sizing

```txt
ZStack {
    Color.yellow
        .frame(width: 50)
    Color.orange
        .frame(height: 50)
}
.border(.red)
.padding()
```

> Interactive example on HTML page: ZStack Sizing.

## ZStack vs. Overlay {#zstack_vs_overlay}

It's not always clear when to use a ZStack and when to use an [overlay](/layout/overlay) or [background](/layout/background). The main difference is that the sizes of the views in a ZStack are independent of each other, while the sizes of the views in an overlay are not. With an overlay, the overlaid view is proposed the size of the primary view. In general, when we want the size of a view to be dependent on the size of another view, we'd use an overlay or background, whereas if they are independent, we use a ZStack. Likewise, when we want to display one view on top of another view without modifying the size of the underlying view, we'd use an overlay.

The example below is similar to the the [badge example](/layout/overlay/#WBeVyU-preview) from the overlay page. However, here we can switch between using a ZStack and an overlay. When we add the badge using a ZStack, the size of the button grows, and the buttons aren't aligned. However, when we use an overlay, the reported size of the button stays the same, and the buttons are aligned.

> Pretty-printed code from ZStack Vs Overlay

```swift
HStack {
    Text("Cart")
        .foregroundStyle(.white)
        .padding(.vertical, 16)
        .padding(.horizontal, 36)
        .background {
            RoundedRectangle(cornerRadius: 8)
                .fill(.blue.gradient)
        }
        .overlay(alignment: .topTrailing) {
            Badge()
                .alignmentGuide(.top) { dim in
                    dim.height / 2
                }
                .alignmentGuide(
                    .trailing
                ) { dim in dim.width / 2 }
        }
        /* .border(.pink) */
    CartButton()
        /* .border(.pink) */
}
```

> Interactive example on HTML page: ZStack Vs Overlay.

In the following example, we use an overlay to display a highlight effect. When we switch to a ZStack, the size of the highlight is not dependent on the size of the text anymore. Instead, the ZStack will grow as large as the rounded rectangle. Because the rounded rectangle is completely flexible, it will take up all the remaining space.

> Pretty-printed code from ZStack Highlight

```swift
HStack {
    Text("One")
    Text("Two")
        .overlay {
            RoundedRectangle(cornerRadius: 8)
                .fill(.purple)
                .opacity(0.5)
                .padding(-8)
        }
    Text("Three")
}
```

> Interactive example on HTML page: ZStack Highlight.

> Pretty-printed code from ZStack Eye

```txt
ZStack {
    Circle()
        .fill(.blue)
    ZStack {
        Circle()
            .fill(.black)
        Circle()
            .fill(.white)
            .frame(width: 50, height: 50)
    }
    .frame(width: 100, height: 100)
}
```

> Interactive example on HTML page: ZStack Eye.

## Alignment Guides {#zstack_alignment_guides}

By using alignment guides with a ZStack, we can create container views that grow to the union of the bounds of the children. Before the [Layout protocol](/layout/layout) was available, we used this technique to build container views. For example, in [this Swift Talk Episode](https://talk.objc.io/episodes/S01E253-flow-layout-revisited), we can see how to build a flow layout using ZStacks and custom alignment guides.
