Merge pull request #392 from JDProfresh/fix/ios-safari-toolbar-gap

fix(mobile): lift the iOS Safari toolbar by the measured chrome overlap
This commit is contained in:
Ark0N
2026-09-10 03:10:12 +02:00
committed by GitHub
2 changed files with 18 additions and 8 deletions
+7
View File
@@ -148,6 +148,13 @@ const MobileDetection = {
if (typeof KeyboardHandler !== 'undefined' && KeyboardHandler.keyboardVisible) return; if (typeof KeyboardHandler !== 'undefined' && KeyboardHandler.keyboardVisible) return;
const vh = window.visualViewport?.height || window.innerHeight; const vh = window.visualViewport?.height || window.innerHeight;
document.documentElement.style.setProperty('--app-height', `${vh}px`); document.documentElement.style.setProperty('--app-height', `${vh}px`);
// How far the layout viewport (which anchors position: fixed) extends below
// the visual viewport, i.e. behind the browser's bottom bar. 0 on iPhone
// Safari, where fixed elements already stop above the bar; the overlap
// where they do not. mobile.css lifts the toolbar by this rather than by
// (100vh - --app-height), which on iPhone measures the collapsible chrome
// instead and left an empty band between the toolbar and the bar.
document.documentElement.style.setProperty('--chrome-overlap', `${Math.max(0, window.innerHeight - vh)}px`);
}, },
/** Initialize mobile detection and set up resize listener */ /** Initialize mobile detection and set up resize listener */
+11 -8
View File
@@ -471,11 +471,11 @@ html.mobile-init .file-browser-panel {
padding-bottom: calc(40px + var(--safe-area-bottom)); padding-bottom: calc(40px + var(--safe-area-bottom));
} }
/* iOS Safari: toolbar is pushed up by (100vh - --app-height) to clear the /* iOS Safari: the toolbar is lifted by --chrome-overlap where the browser's
browser's bottom bar. Match that offset in main's padding so the terminal bottom bar would otherwise cover it. Match that offset in main's padding so
doesn't extend behind the toolbar. */ the terminal doesn't extend behind the toolbar. */
.ios-device.safari-browser .main { .ios-device.safari-browser .main {
padding-bottom: calc(40px + var(--safe-area-bottom) + (100vh - var(--app-height, 100vh))); padding-bottom: calc(40px + var(--safe-area-bottom) + var(--chrome-overlap, 0px));
} }
.header-right { .header-right {
@@ -780,11 +780,14 @@ html.mobile-init .file-browser-panel {
will-change: transform; will-change: transform;
} }
/* iOS Safari with tab bar: position: fixed uses the layout viewport which /* iOS Safari: where position: fixed anchors to a layout viewport that
extends behind the browser chrome. Offset the toolbar upward by the delta extends behind the browser's bottom bar, lift the toolbar by that overlap.
between 100vh (layout) and --app-height (visual). */ --chrome-overlap is innerHeight minus the visual viewport height, set in
mobile-handlers.js. On iPhone Safari it is 0 because fixed elements already
stop above the bar; the previous (100vh - --app-height) lift measured the
collapsible chrome instead and left an empty band above the bar. */
.ios-device.safari-browser .toolbar { .ios-device.safari-browser .toolbar {
bottom: calc(var(--safe-area-bottom) + (100vh - var(--app-height, 100vh))); bottom: calc(var(--safe-area-bottom) + var(--chrome-overlap, 0px));
} }
/* When keyboard is visible the JS translateY already accounts for the full /* When keyboard is visible the JS translateY already accounts for the full