Tutorial8 min read

Edge-to-edge display in Capacitor without plugins

Android 15 makes edge-to-edge mandatory. How to handle edge-to-edge display and safe areas in a Capacitor app with native config and CSS env() — no extra plugin — and ship tweaks over the air.

Android 15 makes edge-to-edge display the default: apps draw behind the status and navigation bars, and it's on you to keep content out from under them. Handled wrong, your header hides behind the clock and your buttons sit under the gesture bar. The good news is you can get this right in a Capacitor app with native config and CSS — no extra plugin — and tune it over the air with OtaKit.

The whole problem is insets: the safe regions the system UI occupies. Native config enables edge-to-edge; CSS env() safe-area variables tell your layout where the edges actually are.

1. Let the WebView go full-bleed

Configure the app to draw behind the system bars (edge-to-edge) and make the status bar transparent. On Android 15 this is increasingly the default; you mainly ensure your theme doesn't fight it.

2. Respect safe areas in CSS

Add the viewport-fit meta tag, then pad your layout with the safe-area insets so content clears the notch, status bar, and gesture bar:

<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1" />
.app-header {
  padding-top: env(safe-area-inset-top);
}
.app-footer {
  padding-bottom: env(safe-area-inset-bottom);
}

3. Test on real hardware

Insets vary wildly — notches, punch-holes, gesture vs button navigation. Test on a couple of real devices, not just the simulator, because that's where the ugly overlaps show up.

4. Iterate the layout over the air

Safe-area handling is pure CSS, which means it's exactly the kind of thing you'll tweak a few times after launch as bug reports come in from devices you didn't test. Ship each adjustment over the air:

otakit upload --release production

The env(safe-area-inset-*) values are zero unless viewport-fit=coveris set. If your padding “does nothing,” that meta tag is almost always the missing piece.

Where to go next

See splash screens for the rest of the launch polish and Setup for the base config.

Related docs