
@capacitor-community/safe-area
Capacitor Plugin that patches the safe area for older versions of Chromium
On web and iOS the safe area insets work perfectly fine out of the box1. That is, on these platforms the env(safe-area-inset-*) CSS variables will have the correct values by default. On Android (in combination with Capacitor), however, those CSS variables will not always have the correct values when Edge-to-Edge mode is enabled. So we need to work some magic in order to achieve the desired behavior. This plugin does that by detecting the Chromium version a user has installed. If a user has a Chromium version lower than 140, this plugin makes sure the webview gets the safe area as a padding. The env(safe-area-inset-*) values will be set to 0px. That means for the Chromium webview versions with a bug, the developer doesn't have to worry about safe area insets at all. For all other versions, the developer should handle the safe area insets just as he would on web or iOS (by using the env(safe-area-inset-*) CSS variables). In short you can think of this plugin as a polyfill for older webview versions.
[!NOTE]
1 As with all (regular) web applications, you still need to tell the browser to scale the viewport as so to fill the device display by setting a viewport meta value like so:
html <meta name="viewport" content="viewport-fit=cover" />More info on the Mozilla website about setting the
<meta name="viewport">and using CSS env().
npm install @capacitor-community/safe-area
npx cap sync
npm install @capacitor-community/safe-area@^7.0.0
npx cap sync
The plugin itself is enabled automatically. Additionally, you should enable native edge-to-edge mode in your MainActivity like so:
Java:
public class MainActivity extends BridgeActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this); // enable edge-to-edge mode
}
}
Kotlin:
class MainActivity : BridgeActivity() {
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge() // enable edge-to-edge mode
}
}
Additionally, this plugin provides helper methods to style the system bars and its content. You can find the API docs here.
This plugin might conflict with some of your existing setup. Please go through the following steps, to ensure proper functioning of this plugin.
If you're installing this plugin into a fresh Capacitor setup, you can probably skip most - if not all - of these steps.
@capacitor/keyboardThe keyboard plugin by Capacitor has a configuration prop called resizeOnFullScreen. You should either omit it or set it to false. Otherwise it would interfere with the logic in this plugin. The bug that the Capacitor team is trying to fix with that prop is already accounted for in this plugin. So you should be good to go a don't worry about it at all.
@capacitor/status-barWhen using @capacitor-community/safe-area, you should uninstall @capacitor/status-bar. Instead you can use the System Bars API this plugin provides.
adjustMarginsForEdgeToEdge settingCapacitor provides a setting called adjustMarginsForEdgeToEdge. It's advised to either omit this value or set it to disable to prevent interference. This plugin already does a similar thing when it detects a broken webview.
windowOptOutEdgeToEdgeEnforcementIf you've set windowOptOutEdgeToEdgeEnforcement in your AndroidManifest.xml, you should probably remove it. It has been deprecated and shouldn't be necessary when using this plugin anyways.
BridgeWebViewClient and calling setWebViewClientIf you're running Capacitor v7 and have extended the BridgeWebViewClient by calling bridge.setWebViewClient in your code, you should update your code so that it extends SafeAreaWebViewClient instead. If you're running Capacitor v8 you do not have to worry about this at all.
If you've installed any other safe area plugin, you should remove them to prevent interference.
Examples of these are: @capawesome/capacitor-android-edge-to-edge-support, capacitor-plugin-safe-area and @aashu-dubey/capacitor-statusbar-safe-area.
Just make sure to uninstall those and you should be good to go.
Alpha versions of this plugin (@capacitor-community/safe-area@alpha) are deprecated and usage of those versions is advised against. Please migrate to a latest channel instead. Differences between the older versions and the newer versions are outlined here.
If you're running Capacitor v8, you should set the following in your capacitor.config.json:
{
"plugins": {
"SystemBars": {
"insetsHandling": "disable"
}
}
}
system-bars and status-barThe main differences are as follows:
@capacitor-community/safe-area |
CapacitorSystemBars5 |
@capacitor/status-bar |
|
|---|---|---|---|
| Supported Capacitor versions | ✅ v7+ | ⚠️ v8+ | ✅ v7+ |
| Helper methods for styling and hiding the system bars | ✅ | ✅ | ✅ |
| Updates styling of system bars upon config changes | ✅ | ✅ | ✅ |
| Enables Edge to Edge functionality | ✅ | ✅ | ❌ |
| Option to opt out of handling insets for Android | ✅ | ❌ | N/A |
| Philosophy2 | ✅ Native approach. Aligns with iOS and web behavior. Does not require extra work. Fallback to padding for broken webviews. | ⚠️ All or nothing approach using custom CSS vars injection. Requires extra work (migrating from envs to vars). Doesn't distinguish between broken and fixed webview versions. It's arguably more prone to future bugs. | N/A |
| Fallback supported on Android versions | ✅ Android 6+ | ❌ Android 15+ (broken behavior on older versions) | N/A |
| Workaround for resizing keyboard bug3 | ✅ Working out of the box | ⚠️ Requires installing @capacitor/keyboard and setting resizeOnFullScreen. Their workaround also still has bugs |
❌ |
| Workaround for inset keyboard bug4 | ✅ Working out of the box | ❌ | N/A |
Detects viewport-fit=cover changes |
✅ Works for any arbitrary web content | ⚠️ Works only for web content that has Capacitor v8 set up | N/A |
2 Chromium versions < 140 do not correctly report safe area insets. So we need a workaround for those webviews. This can be done using padding or custom CSS vars. This plugin advocates for using padding. As it seems to be the least breaking behavior.
3 The webview has a known bug to not resize the webview when the keyboard is shown.
4 The webview has another known bug to not properly report bottom insets when the keyboard is shown. Which will be fixed in Chromium 144
5 The Capacitor team themselves are also working on a similar
solution by means of a CapacitorSystemBars plugin. It's still a
work in progress though. Currently that PR is merged as is and in a beta state. Their design/approach philosophy also
deviates from the one in this plugin.
You probably do! Apps targeting Android sdk version 36 will automatically be in edge to edge mode on a device running Android 16+. This means you should properly support safe area insets. This seemingly works just fine. However Chromium versions < 140 have a bug that causes the webview to receive incorrect values (0px). This plugin works around that by adding a padding to the webview for those devices. As a bonus, this plugin resizes the webview upon keyboard visibility changes, something that also isn't standard.
They can and they should. They tried / are trying actually. But IMHO their approach isn't ready for production (yet). The differences between their approach and the one of this plugin are outlined here. I try to adhere to their coding style and I am actively providing feedback to the Capacitor team in hopes they will - sometime - upstream this plugin into th
$ claude mcp add safe-area \
-- python -m otcore.mcp_server <graph>