MobileCheck

Safe Area Insets: Keep Content Clear of the Notch and Home Bar

Updated October 20, 2026

Short answer: Safe area insets are the distances from each screen edge covered by the notch or Dynamic Island, rounded corners and the home indicator. Add viewport-fit=cover to the viewport tag only if you want to draw edge to edge, then pad content with env(safe-area-inset-top), -right, -bottom and -left, for example padding-bottom: max(16px, env(safe-area-inset-bottom)) on a fixed bottom bar.

To keep content clear of the notch, the Dynamic Island, rounded corners and the home indicator, pad it with env(safe-area-inset-*). You only need this if you opt in to edge-to-edge drawing with viewport-fit=cover; without it, the browser keeps your page inside the safe area for you. Always wrap the inset in max() so the padding never drops to zero on devices without insets.

What are safe area insets?

Modern phones aren't rectangles. They have rounded corners, a camera notch or Dynamic Island, and on iPhones without a Home button a home indicator bar at the bottom. The safe area is the part of the screen that none of these cover. The four insets, top, right, bottom and left, are the distances from each edge to that safe area, in CSS pixels.

The browser exposes them as environment variables you read with env():

env(safe-area-inset-top)
env(safe-area-inset-right)
env(safe-area-inset-bottom)
env(safe-area-inset-left)

When there is nothing to avoid, they are 0px. They change with orientation: on an iPhone in landscape, the notch side gets a large left or right inset, while in portrait the bottom inset for the home indicator is the one that usually matters.

Why does viewport-fit=cover matter?

By default, Safari keeps the page inside the safe area. In landscape on a notched iPhone that means bands at the sides filled with the page's background color. That's safe, but it can look odd if your header has a different color from the body.

Adding viewport-fit=cover to your viewport meta tag tells the browser to draw the page across the whole screen:

<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">

From then on, keeping text and buttons out from under the notch and the home indicator is your job. Add viewport-fit=cover only together with the padding below; on its own it can push content under the hardware.

How do I use env() with a fallback?

A raw inset is zero on most screens, which would leave content touching the edge. Combine it with your normal spacing using max(), so you get whichever is larger:

.site-header,
.site-footer,
.content {
  padding-left: max(1rem, env(safe-area-inset-left));
  padding-right: max(1rem, env(safe-area-inset-right));
}

For a background that should run under the notch while the content stays clear, put the color on the full-width element and the inset in its padding. The background fills the edge; the text doesn't.

The same idea works for a sticky header in a home-screen web app, where the top inset covers the status bar and the camera:

.site-header {
  position: sticky;
  top: 0;
  padding-top: env(safe-area-inset-top);
  background: var(--header-bg);
}

Insets can also be used in calc(), for example height: calc(56px + env(safe-area-inset-bottom)) for a tab bar whose icons should keep their 56px row above the home indicator. Prefer padding with min-height where you can, because it adapts better to large text.

How do I fix fixed bottom bars and floating buttons?

Bottom navigation, cookie bars and "Buy" buttons fixed to the bottom of the screen are where safe areas matter most. Without padding, their buttons sit right on the home indicator, where a swipe can close the browser instead of tapping your button.

.bottom-nav {
  position: fixed;
  inset: auto 0 0 0;
  min-height: 56px;
  padding-bottom: max(0.5rem, env(safe-area-inset-bottom));
}

.chat-button {
  position: fixed;
  right: max(16px, env(safe-area-inset-right));
  bottom: calc(16px + env(safe-area-inset-bottom));
}

If other content needs to stay above the bar, add the same inset to the body's bottom padding so the last paragraph isn't hidden behind it. And keep the bar small: together with a sticky header it shouldn't take more than a modest share of the screen, as the sticky headers guide explains.

On iPhone vs Android

Common mistakes

How do I check it?

Safe areas depend on the physical device. MobileCheck's emulated browsers have no notch and report zero insets, so the free check confirms that your layout and padding fallbacks work at each device's width and height, but it can't show content under the notch. For that, open the page on a real iPhone with a notch or Dynamic Island, in portrait and landscape, and scroll so Safari's toolbar collapses. If you work on a Mac, Apple's iOS Simulator in Xcode runs real Safari with real safe areas. For the related problem of full-height sections and Safari's toolbar, see 100vh on mobile.

Frequently asked questions

Do I need viewport-fit=cover?

Only if you want your page to extend under the notch and rounded corners. Without it, Safari keeps the page inside the safe area automatically. If you add it, pad your content with env(safe-area-inset-*).

Why is env(safe-area-inset-bottom) zero?

Insets are zero when nothing covers that edge: on phones with a Home button, in many Android setups, or when the page does not use viewport-fit=cover. Wrap the inset in max() so your normal padding still applies.

Does Android support safe area insets?

Yes. Chrome on Android exposes the same env(safe-area-inset-*) variables for camera cutouts and, in recent versions, for edge-to-edge display. On many devices the values are simply zero.

Sources

Related guides