Repository navigation
Description
Bug Report
Plugin(s)
@capacitor/status-bar8.0.4@capacitor/browser8.0.5 (used to present the full-screen modal)
Capacitor Version
Installed Dependencies:
@capacitor/android: not installed
@capacitor/cli: 8.6.0
@capacitor/core: 8.6.0
@capacitor/ios: 8.6.0
[success] iOS looking great! 👌
Platform(s)
iOS
Current Behavior
With overlaysWebView: false, the WebView starts below the status bar after launch. After a full-screen modal is dismissed, the WebView fills the whole window again:
- The page content sits under the status bar.
- The status bar background view (
backgroundColor) is no longer visible. StatusBar.getInfo()still returnsoverlays: false.
The layout stays wrong until the next rotation. Rotating to landscape and back restores it.
The full-screen modal in the reproduction is Browser.open() with the default presentation style. With presentationStyle: 'popover' the layout stays correct.
Expected Behavior
After a full-screen modal is dismissed, the WebView is below the status bar again, and the status bar background view is visible, as before the modal was presented.
Code Reproduction
https://github.com/kidzki/capacitor-status-bar-repro
npm install && npm run build && npx cap sync ios- Run the app on an iPhone simulator. The yellow box shows
RESULT: OK. - Tap Open in-app browser (full screen), then close the browser.
- The yellow box shows
RESULT: BUG:window.innerHeightequalsscreen.height, and the sticky header sits under the status bar.
Configuration:
"StatusBar": {
"overlaysWebView": false,
"backgroundColor": "#ffffff",
"style": "LIGHT"
}Other Technical Details
- Observed on the iPhone 18 Pro simulator, iOS 27.2, Xcode 27.2.
- Also observed in our app on a physical iPhone 17 Pro with iOS 26.6.4, 27.0.1 and 27.2. Our app opens
Browser.open()full screen for the login. - The page does not use
viewport-fit=cover. - The app shell is the unchanged
iostemplate fromnpx cap add ios(Capacitor 8.6.0).
Additional Context
CAPBridgeViewController.loadView() sets view = webView, so the WebView is the root view. When a full-screen modal is dismissed, UIKit sets the root view back to the full window bounds.
The plugin positions the WebView in resizeWebView(). It calls that function after setOverlaysWebView and after a rotation (capacitorViewWillTransition). On capacitorViewDidAppear, which also fires after the modal is dismissed, handleViewDidAppear calls setOverlaysWebView(config.overlaysWebView). That function returns early because the value did not change (if overlay == isOverlayingWebview { return }), so the plugin does not lay out the WebView again.
Possible fixes:
- Lay out again in
handleViewDidAppear. We tried this: it restores the layout, but the jump is visible becauseviewDidAppearfires after the dismiss animation. - Observe the WebView layer (
position,bounds) whileoverlaysWebViewisfalse, and move the WebView back below the status bar when its origin changes. We tried this: the layout is restored without a visible jump. A pull request with this change follows. - Capacitor core sends a notification from
viewWillLayoutSubviewsorviewWillAppear, and the plugin lays out there. Not tried. @capacitor/browserpresents with.overFullScreeninstead of.fullScreen, so UIKit keeps the presenting view in place. Not tried. This fixes only the browser, not other full-screen modals.
Activity