---
title: "Overlay"
description: "The overlay modifier lets us overlay a view on another view."
url: https://www.swiftuifieldguide.com/layout/overlay
markdown_url: https://www.swiftuifieldguide.com/layout/overlay.md
---
> Convenience Markdown export of the HTML page. Interactive samples, diagrams, and visualizations stay on the canonical page.
# Overlay

Overlay is a simple yet powerful modifier that overlays a view on another view. For example, here's a text view with a blue overlay:

> Pretty-printed code from Sample0

```swift
Text("Hello, world. This is a longer text.")
    .overlay {
        Color.blue
            .opacity(0.2)
    }
```

> Interactive example on HTML page: Sample0.

In the example above, the blue color matches the bounding box of the text exactly. This is no coincidence. During layout, the overlay takes the reported size of the text and proposes it to its secondary child (the blue color):

> Interactive example on HTML page: Sample1.

In general, when you want the size of the overlaid view to be dependent on the size of the primary view, you should use the overlay modifier. This is because the overlay modifier proposes the size of the primary view to the secondary view. When you want the sizes of these two views to be independent, you should consider using a [ZStack](/layout/zstack) instead. If you want the same dependent sizing behavior but behind the primary view, see [background](/layout/background).

The reported size of the overlay is the size of the primary child. While we don't see the difference in an isolated example, it becomes more important when the view is surrounded by other views. For example, we can overlay a view with negative padding around an existing view without influencing the layout:

> Pretty-printed code from Sample2

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

> Interactive example on HTML page: Sample2.

Overlay also provides an alignment parameter, and the default is `.center`. This works as expected:

> Pretty-printed code from Sample3

```swift
Color.purple
    .frame(width: 100, height: 100)
    .overlay {
        Text("Hi")
    }
```

> Interactive example on HTML page: Sample3.

One of the most useful parts of `overlay` is that it proposes the size of its primary child to its secondary child. However, there are cases where we might not want this behavior. In the example below, we have a badge view similar to the one on the [alignment](/layout/alignment) page. When we apply it on a large enough view, it renders fine. However, when the primary child is small, the badge gets proposed a small size as well and can truncate the text. To decouple the sizes, we can apply the `fixedSize` modifier to the badge view.

> Pretty-printed code from Badge

```txt
BuyButton()
    .overlay(alignment: .topTrailing) {
        MyBadge()
            /* .fixedSize() */
            .alignmentGuide(.top) { dim in
                dim.height / 2
            }
            .alignmentGuide(.trailing) { dim in
                dim.width / 2
            }
    }
```

> Interactive example on HTML page: Badge.

On the [ZStack](/layout/zstack) page we can look at a [similar example](/layout/zstack#aEfkfZ-preview) of a badge view, but built with a ZStack.
