You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat: Support new edge-to-edge enforcement introduced in Android 15 (API 35) #30090
I have searched for existing issues that already include this feature request, without success.
Describe the Feature Request
When running an app targeting SDK 35 in an Android 15 device, now the app fills the whole screen (it no longer leaves some margins for the bottom Android buttons for example). This means that some content might be behind the Android buttons, making that content unclickable.
I'm not sure if the best solution is that cordova-android applies margins to the WebView so it doesn't fill the full screen, making it behave similar to how it behaves in Android 14, or it should be Ionic the one handling those margins (I guess using the "safe area"). I'd prefer the latter because it will look similar to a native Android app, that's why I open this issue.
Right now cordova-android only supports SDK 34, it still doesn't support SDK 35.
To reproduce the issue, just add this in your config.xml and run an app in a device with Android 15:
I'll chime in too, just to highlight that this needs some attention. I've been experimenting with migrating to SDK 35 to support Android 15 and have run into this edge-to-edge problem as well. Targeting SDK 35 in variables.gradle:
compileSdkVersion = 35
targetSdkVersion = 35
And running the Ionic "sidemenu" starter template app in the Android 15 emulator produces this display:
(I changed the ion-toolbar background color to "warning" (i.e. yellow) for emphasis)
Note the Ionic toolbar renders underneath the Android status bar at the top, and the app's main page renders under the navigation bar at the bottom (with gesture navigation turned off). This is Android's edge-to-edge display paradigm.
As @dpalou mentions you can work-around this issue by adding the windowOptOutEdgeToEdgeEnforcement attribute to android/app/src/main/res/values-v35/styles.xml:
Just experienced the same problem and the fix above worked. Question, though -- I would think this belongs in the capacitor repository not the ionic one? Seems like the fix might be around Java code to detect the inset sizes and react appropriately (as indicated here: https://developer.android.com/develop/ui/views/layout/edge-to-edge#java. . I'm happy to create the bug there if you agree.
There's already an issue flagged on the capacitor GitHub page ionic-team/capacitor#7804. It was added pretty recently, so not much activity so far.
I think this should also be flagged in this repository, because using the windowOptOutEdgeToEdgeEnforcement attribute as a temporary work-around should be added to the Ionic Android scaffolding until Capacitor can make some progress with insets.
@moose4lord this solution worked on my device API 34 but the low-end device with API 29 not. Just for the record. I will try to use the community plugin for the API 29.
Also waiting for a fix.
Just updated our application to Capacitor 7, using minSDK 31, Target 35, tested on a Samsung Galaxy A23 running 34, the Navigation bar goes above our design. And same goes for the top part, which goes behind the status bar.
Any quick fix?
Reacted by Daniel Ehrhardt, Fabian Chacon, Yura, mla03, Mudassir khan and BestCodes
I've just published the Android Edge-to-Edge Support plugin, which applies an insert to the web view to restore the previous look. You just need to install it, and your done:
npm i @capawesome/capacitor-android-edge-to-edge-support
Optionally, you can also change the background color of the status and navigation bar. Let me know if you encounter any problems by creating an issue or discussion in capawesome-team/capacitor-plugins.
Reacted by Nabeel Akbar and Marius
Reacted by Matheus Felipe and Engin Atalay
Reacted by Tom Westrick, Daniel Ehrhardt, Nans Marchis-Mouren, Hans, Don Omondi, Fran González, Thibault, Sergio Milici, Calvin Woo, Bittor Poza and 5 more
Update: A GitHub PR (#7871) in the Capacitor repository has been approved to address this issue. I hacked the changes to the CapacitorWebView.java file and the PR seems to work well.
This fix has not been released yet, but look for it in the upcoming Capacitor v7.0.2 release. I doubt they will backport the code to Capacitor 6, so you'll probably have to migrate to Capacitor 7 if you haven't done so already.
I'm not sure when the next release will happen. They tend to make releases on a monthly cadence, so since 7.0.1 was released about 3 weeks ago, I'm guessing it will be pretty soon. On the other hand, there's a nasty bug (#7866) in the current Android dependencies that needs to get worked out before the next release. So who knows?
Disable overlaysWebView in capacitor.config.js (set to false in capacitor.config.ts)
plugins: { StatusBar: { overlaysWebView: false } }
(exemple if you use capacitor.config.ts)
This function was not automatically call before.... In Capacitor 7 there was a refactoring and now, setOverlaysWebView is called in the StatusBar constructor and make the app looking "edge-to-edge".
Verified on 9.0.6. Ionic pads headers, footers, tab bars and other components using --ion-safe-area-*, which defaults to the WebView's env(safe-area-inset-*) values. When Android 15 started drawing apps edge-to-edge, Android WebView versions before 140 reported those values as 0 because of a Chromium bug, so there was nothing to pad by and content ended up under the status and navigation bars.
This is now supported. Capacitor 8 injects the real insets as --safe-area-inset-* CSS variables, and #30865 made Ionic read those first, falling back to env(). It shipped in v8.7.15. A follow-up, #31343, makes translucent headers pick up the inset when it arrives after the first render, and shipped in v8.8.18.
To get it, update to Capacitor 8 and Ionic 8.7.15 or later (8.8.18 or later if you use translucent headers). No extra configuration is needed, since Capacitor 8 loads its SystemBars plugin with insetsHandling: 'css' by default.
A few workarounds from earlier in this thread no longer apply:
android.adjustMarginsForEdgeToEdge was a Capacitor 7 option and was removed in Capacitor 8, so setting it has no effect there.
android:windowOptOutEdgeToEdgeEnforcement is ignored by Android for apps targeting SDK 36, which is Capacitor 8's default.
Setting --ion-safe-area-top manually from StatusBar.getInfo() is no longer needed, only covers the top edge, and overrides the value Ionic now reads for you. Remove it after upgrading.
If you are on Cordova, cordova-android 15 keeps content out from under the system bars by default. With AndroidEdgeToEdge enabled, Ionic pads correctly on Android WebView 140 and later.
Since a lot of people have been following this, could someone on Capacitor 8 and Ionic 8.7.15 or later confirm it works in your app? If you still see content under the system bars on the latest versions, please share a minimal reproduction.
Capacitor 8 and Ionic 8.7.15 or later confirm it works in your app?
Deployed two apps with Capacitor 8.5.2 and Ionic 9.0.4. I can confirm that it works.
I removed all the windowOptOutEdgeToEdgeEnforcement usages. Removed overlaysWebView: false from the StatusBar plugin.
Important that if you don't have a theme that supports dark mode to add this to your "capacitor.config.ts" plugins section. Without it the device controls will be very hard to see for the user.
SystemBars: {// The app is always light-themed, but without this the status/navigation bar icon color// defaults to following the device's system dark/light mode instead, so on a device in// system dark mode the icons render light-on-light and become nearly invisible.style: 'LIGHT',},
Some specific mitigations that I applied. The inline comments are very verbose because of 🤖.
Extra padding in my "src/theme/variables.css". Without it the device controls will go over the content. This is by no means a use it for everything fix, it works for my specific use cases. Is is a collection of mitigations over both app.
/*ion-content only gets automatic safe-area padding when it's inside an ion-modal; on a regularrouted page it doesn't reserve any space for the edge-to-edge Android navigation bar (bottom, or aside edge in landscape with 3-button navigation), so content can render underneath/behind it.Some pages also set the `ion-padding` utility class on their ion-content, which sets its own fixed16px --padding-*; that class selector beats a plain `ion-content` element selector on specificity,so it has to be matched (and added to, via calc) explicitly here too, or it silently wins and thisrule does nothing on exactly the pages that need it.*/ion-content {
--padding-bottom:var(--ion-safe-area-bottom);
--padding-start:var(--ion-safe-area-left);
--padding-end:var(--ion-safe-area-right);
}
ion-content.ion-padding {
--padding-bottom:calc(var(--ion-padding,16px) +var(--ion-safe-area-bottom));
--padding-start:calc(var(--ion-padding,16px) +var(--ion-safe-area-left));
--padding-end:calc(var(--ion-padding,16px) +var(--ion-safe-area-right));
}
/*Drop the bottom safe-area padding from ion-content when an ion-footer directly follows it, becausethat footer already takes care of the safe area.`footer-toolbar-padding` is a class Ionic itself puts on ion-footer: ion-footer adds it while thekeyboard is hidden and there's no ion-tab-bar at the bottom of the page, and removes it otherwise.While it's present, Ionic gives the footer's last ion-toolbar`padding-bottom: var(--ion-safe-area-bottom)`, so the footer covers the unsafe area at the bottomof the screen and ion-content ends at the footer's top edge, clear of that area. Our globalion-content rules above would add --ion-safe-area-bottom to the content as well, counting it twiceand leaving a blank gap between the content and the footer.*/ion-content:has(+ion-footer.footer-toolbar-padding) {
--padding-bottom:0px;
}
ion-content.ion-padding:has(+ion-footer.footer-toolbar-padding) {
--padding-bottom:var(--ion-padding,16px);
}
/*Inside a full-screen ion-modal, Ionic already adds the bottom safe area to ion-content itself (viaits internal --internal-content-safe-area-padding-bottom, on top of --padding-bottom), so the ruleabove would reserve that space twice. Reset just the bottom back to Ionic's own default there; thestart/end insets aren't handled by the modal and still apply. Sheet and card modals don't get thatinternal padding, so revisit this if one is ever added.*/ion-modalion-content {
--padding-bottom:0px;
}
/*The top safe area is normally reserved by an ion-header's toolbar. A full-screen ion-modal withoutone would otherwise put its content under the status bar. Ionic sets --ion-safe-area-top to 0px onmodals that don't touch the top edge (sheet, card, centered ontablets), so this only adds space whereit's needed.*/ion-modal:not(:has(ion-header)) ion-content {
--padding-top:var(--ion-safe-area-top);
}
Thanks for confirming, @robkorv, and for the SystemBars tip!! Capacitor's default style follows the device's dark mode setting, so style: 'LIGHT' is the right call for an app that is always light-themed.
The extra ion-content padding covers a separate gap: ion-content on a regular page doesn't reserve safe-area space when there is no header or footer. That is tracked in #30900, so please follow along there. One caution for anyone copying those rules: ion-item, ion-item-divider and ion-list-header already add the left and right safe area themselves, so the --padding-start and --padding-end rules on ion-content pad lists twice in landscape.
Since this works on Capacitor 8 with Ionic 8.7.15 or later, I'm closing this one. If you still see content under the system bars on the latest versions, please open a new issue with a minimal reproduction.
Activity
moose4lord commentedon Dec 23, 2024
I'll chime in too, just to highlight that this needs some attention. I've been experimenting with migrating to SDK 35 to support Android 15 and have run into this edge-to-edge problem as well. Targeting SDK 35 in variables.gradle:
And running the Ionic "sidemenu" starter template app in the Android 15 emulator produces this display:

(I changed the ion-toolbar background color to "warning" (i.e. yellow) for emphasis)
Note the Ionic toolbar renders underneath the Android status bar at the top, and the app's main page renders under the navigation bar at the bottom (with gesture navigation turned off). This is Android's edge-to-edge display paradigm.
As @dpalou mentions you can work-around this issue by adding the windowOptOutEdgeToEdgeEnforcement attribute to android/app/src/main/res/values-v35/styles.xml:
Which produces this display:

davideshay commentedon Dec 25, 2024
Just experienced the same problem and the fix above worked. Question, though -- I would think this belongs in the capacitor repository not the ionic one? Seems like the fix might be around Java code to detect the inset sizes and react appropriately (as indicated here: https://developer.android.com/develop/ui/views/layout/edge-to-edge#java. . I'm happy to create the bug there if you agree.
moose4lord commentedon Dec 25, 2024
There's already an issue flagged on the capacitor GitHub page ionic-team/capacitor#7804. It was added pretty recently, so not much activity so far.
I think this should also be flagged in this repository, because using the windowOptOutEdgeToEdgeEnforcement attribute as a temporary work-around should be added to the Ionic Android scaffolding until Capacitor can make some progress with insets.
Tomjech16 commentedon Jan 9, 2025
Any news? There are problems with existing capacitor plugins like splash screen as well, because of new edge-to-edge.
danpercic86 commentedon Jan 22, 2025
I have the same issue, the app is unusable starting with Android 15
mfcarneiro commentedon Jan 23, 2025
@moose4lord this solution worked on my device API 34 but the low-end device with API 29 not. Just for the record. I will try to use the community plugin for the API 29.
danielehrhardt commentedon Jan 27, 2025
pls fix
mla03 commentedon Jan 30, 2025
Also waiting for a fix.
Just updated our application to Capacitor 7, using minSDK 31, Target 35, tested on a Samsung Galaxy A23 running 34, the Navigation bar goes above our design. And same goes for the top part, which goes behind the status bar.
Any quick fix?
AvniAnay commentedon Jan 31, 2025
I am facing the same issue , some times footer is also overlapped
DevDianDankie commentedon Feb 1, 2025
bump - same
robingenz commentedon Feb 6, 2025
I've just published the Android Edge-to-Edge Support plugin, which applies an insert to the web view to restore the previous look. You just need to install it, and your done:
Optionally, you can also change the background color of the status and navigation bar. Let me know if you encounter any problems by creating an issue or discussion in capawesome-team/capacitor-plugins.
moose4lord commentedon Feb 7, 2025
Update: A GitHub PR (#7871) in the Capacitor repository has been approved to address this issue. I hacked the changes to the CapacitorWebView.java file and the PR seems to work well.
This fix has not been released yet, but look for it in the upcoming Capacitor v7.0.2 release. I doubt they will backport the code to Capacitor 6, so you'll probably have to migrate to Capacitor 7 if you haven't done so already.
Many thanks to @markemer for the fix.
donqemal commentedon Feb 10, 2025
@moose4lord do we know, when Capacitor v7.0.2 will be released?
moose4lord commentedon Feb 10, 2025
I'm not sure when the next release will happen. They tend to make releases on a monthly cadence, so since 7.0.1 was released about 3 weeks ago, I'm guessing it will be pretty soon. On the other hand, there's a nasty bug (#7866) in the current Android dependencies that needs to get worked out before the next release. So who knows?
22 remaining items
Luise8 commentedon Aug 12, 2025
@dennisfcp why? where did you see this?
TiBz0u commentedon Aug 20, 2025
Force will work for me too because margin are calculated through windowInsets (https://github.com/ionic-team/capacitor/blob/a571724c3238c510bc3991413d1a27222cc47685/android/capacitor/src/main/java/com/getcapacitor/CapacitorWebView.java#L58)
However, the android attribute windowOptOutEdgeToEdgeEnforcement (https://developer.android.com/reference/android/R.attr#windowOptOutEdgeToEdgeEnforcement) is normally deprecated in Android 16 (https://developer.android.com/about/versions/16/behavior-changes-16?hl=fr) [API 36].
Purpose of this attribute is to keep same behavior as before API 35
Android 16 will be the default in Capacitor 8.
That's certainly the point he mention but it's another approach (manually adapt the android theme).
Don't hesitate to react if I'm wrong :)
Prioritise usable tabs in Android 15+ over nice status bar for now
markemer commentedon Aug 28, 2025
In Capacitor 8 this should "just work" but 7 will need one of these 2:
Sina7312 commentedon Sep 22, 2025
I've fixed this issue this way:
TiBz0u commentedon Oct 6, 2025
Hi everyone,
After struggling with the edge-to-edge to stay on Android 14 behavior, here my final solution.
There are two steps.
<item name="android:windowOptOutEdgeToEdgeEnforcement" tools:targetApi="35">true</item>plugins: { StatusBar: { overlaysWebView: false } }(exemple if you use capacitor.config.ts)
This function was not automatically call before.... In Capacitor 7 there was a refactoring and now,
setOverlaysWebViewis called in theStatusBarconstructor and make the app looking "edge-to-edge".``
See https://capacitorjs.com/docs/apis/status-bar#configuration
Kr.
TiBz0u
thetaPC commentedon Oct 2, 2026
Thanks for the report, and sorry for the delay.
Verified on 9.0.6. Ionic pads headers, footers, tab bars and other components using
--ion-safe-area-*, which defaults to the WebView'senv(safe-area-inset-*)values. When Android 15 started drawing apps edge-to-edge, Android WebView versions before 140 reported those values as0because of a Chromium bug, so there was nothing to pad by and content ended up under the status and navigation bars.This is now supported. Capacitor 8 injects the real insets as
--safe-area-inset-*CSS variables, and #30865 made Ionic read those first, falling back toenv(). It shipped in v8.7.15. A follow-up, #31343, makes translucent headers pick up the inset when it arrives after the first render, and shipped in v8.8.18.To get it, update to Capacitor 8 and Ionic 8.7.15 or later (8.8.18 or later if you use translucent headers). No extra configuration is needed, since Capacitor 8 loads its
SystemBarsplugin withinsetsHandling: 'css'by default.A few workarounds from earlier in this thread no longer apply:
android.adjustMarginsForEdgeToEdgewas a Capacitor 7 option and was removed in Capacitor 8, so setting it has no effect there.android:windowOptOutEdgeToEdgeEnforcementis ignored by Android for apps targeting SDK 36, which is Capacitor 8's default.--ion-safe-area-topmanually fromStatusBar.getInfo()is no longer needed, only covers the top edge, and overrides the value Ionic now reads for you. Remove it after upgrading.If you are on Cordova, cordova-android 15 keeps content out from under the system bars by default. With
AndroidEdgeToEdgeenabled, Ionic pads correctly on Android WebView 140 and later.Since a lot of people have been following this, could someone on Capacitor 8 and Ionic 8.7.15 or later confirm it works in your app? If you still see content under the system bars on the latest versions, please share a minimal reproduction.
robkorv commentedon Oct 5, 2026
Deployed two apps with Capacitor 8.5.2 and Ionic 9.0.4. I can confirm that it works.
I removed all the
windowOptOutEdgeToEdgeEnforcementusages. RemovedoverlaysWebView: falsefrom the StatusBar plugin.Important that if you don't have a theme that supports dark mode to add this to your "capacitor.config.ts"
pluginssection. Without it the device controls will be very hard to see for the user.Some specific mitigations that I applied. The inline comments are very verbose because of 🤖.
Extra padding in my "src/theme/variables.css". Without it the device controls will go over the content. This is by no means a use it for everything fix, it works for my specific use cases. Is is a collection of mitigations over both app.
thetaPC commentedon Oct 5, 2026
Thanks for confirming, @robkorv, and for the
SystemBarstip!! Capacitor's default style follows the device's dark mode setting, sostyle: 'LIGHT'is the right call for an app that is always light-themed.The extra
ion-contentpadding covers a separate gap:ion-contenton a regular page doesn't reserve safe-area space when there is no header or footer. That is tracked in #30900, so please follow along there. One caution for anyone copying those rules:ion-item,ion-item-dividerandion-list-headeralready add the left and right safe area themselves, so the--padding-startand--padding-endrules onion-contentpad lists twice in landscape.Since this works on Capacitor 8 with Ionic 8.7.15 or later, I'm closing this one. If you still see content under the system bars on the latest versions, please open a new issue with a minimal reproduction.