The Problem
When you set viewport-fit=cover to create an edge-to-edge experience, the browser renders your content under the Dynamic Island, notch, and home indicator bar. Headers get hidden behind the pill; bottom nav bars slide under the home indicator.
Content overlapping Dynamic Island & home bar
Root Cause
Starting with iPhone X (2017), Apple introduced non-rectangular screen areas — the notch, then the Dynamic Island. When viewport-fit=cover is added to the viewport meta tag, the browser renders content edge-to-edge to fill the rounded corners. But the iOS hardware UI (Dynamic Island, home indicator) sits on top of your content and covers it.
iOS exposes the safe zones as CSS environment variables via env(), allowing you to pad your content away from these hardware elements.
viewport-fit=cover, the browser adds letter-box padding and safe areas are automatically respected — but you lose the edge-to-edge look. The env() fix is only needed when you opt into cover mode.Step 1 — Enable edge-to-edge
<meta
name="viewport"
content="width=device-width, initial-scale=1, viewport-fit=cover"
>Step 2 — Pad with env() variables
/* Apply safe area padding to UI chrome elements */
.app-header {
padding-top: env(safe-area-inset-top);
}
.app-footer,
.bottom-nav {
padding-bottom: env(safe-area-inset-bottom);
}
/* Left/right for landscape mode (iPhone notch rotates) */
.app-shell {
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
}
/* Combine with a minimum padding using max() */
.bottom-nav {
padding-bottom: 12px;
padding-bottom: max(12px, env(safe-area-inset-bottom));
}
/* Add to an existing padding using calc() */
.sticky-footer {
padding-bottom: calc(1rem + env(safe-area-inset-bottom));
}max(20px, env(safe-area-inset-bottom)) ensures at least 20px of padding on older devices where the safe-area value is 0, while correctly applying the larger inset value on modern iPhones.The four env() variables
/* Available environment variables */
env(safe-area-inset-top) /* Dynamic Island / status bar height */
env(safe-area-inset-right) /* Right edge (landscape notch side) */
env(safe-area-inset-bottom) /* Home indicator height (~34px on iPhone) */
env(safe-area-inset-left) /* Left edge (landscape non-notch side) */Browser Support
| Browser | Min Version | Status | Notes |
|---|---|---|---|
| Safari iOS 11+ | 11+ | Supported | env(safe-area-inset-*) fully supported |
| Safari iOS < 11 | < 11 | Supported | No non-rectangular screens — safe area is 0, no issue |
| Chrome iOS | All | Supported | Same WebKit engine, same env() support |
| Chrome Android | 69+ | Supported | env() supported; Android handles notches differently |
| Firefox | 65+ | Supported | env(safe-area-inset-*) supported |
| Samsung Internet | 9+ | Supported | Supported for Samsung devices with notches |
Further Reading
- WebKit Blog: "Designing Websites for iPhone X"The original WebKit blog post introducing safe area insets and viewport-fit=cover.
- MDN: env()Complete documentation for the env() CSS function and all supported environment variables.
- Apple Developer: Safe Area Layout GuideApple's design guidelines for respecting safe areas in iOS applications.