Phone layout: make the whole document reach the bottom in the home-screen app

Sizing the stage from the screen height was not enough on iOS 26: with the layout
viewport a status bar short, WebKit clips at the short viewport and draws nothing
below the document, so the dock still floated over a dark strip. In standalone mode
`<html>` now takes the larger of `100vh` and the screen height too, and the stage
follows it.

Coming back from the background, or a relaunch restoring the page, is when iOS is most
likely to hand back a short viewport and it does not always fire `resize`, so the
height is also re-applied on `pageshow` and `visibilitychange`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 10:29:50 +02:00
parent 34656a8517
commit f67f84ded3
2 changed files with 19 additions and 7 deletions

View File

@@ -13,17 +13,25 @@
--m-dock-clearance: calc(96px + env(safe-area-inset-bottom));
}
/* iOS can leave the layout viewport shorter than the screen in a home-screen app -
`100dvh`, and even `position: fixed; inset: 0`, come back one status bar short - so
the dock floated that far above the bottom with an empty strip below it. There the
stage takes its height from the screen instead (`--full-height` and
`data-standalone`, set by lib/fullHeight.ts only in standalone mode); everywhere else it pins to the viewport.
The sea colour underneath covers whatever might still peek through. */
/* iOS 26 can leave the layout viewport of a home-screen app one status bar short -
`100dvh`, `innerHeight` and `position: fixed; inset: 0` all come back short, and
WebKit draws nothing below the document - so the dock floated that far above the
bottom over a dark strip. Sizing the stage alone was not enough: it got clipped at
the short viewport. The document itself has to reach the bottom of the screen, so in
standalone mode (`data-standalone` and `--full-height`, set by lib/fullHeight.ts)
`<html>` takes the larger of `100vh` and the screen's height, and the stage follows.
Everywhere else the stage just pins to the viewport. The sea colour underneath
covers whatever might still peek through. */
html,
body {
background: var(--stage-deep, #001b21);
}
:root[data-standalone] {
height: max(100vh, var(--full-height, 0px));
overflow: hidden;
}
.stage[data-phone] {
position: fixed;
inset: 0;
@@ -32,7 +40,7 @@ body {
:root[data-standalone] .stage[data-phone] {
bottom: auto;
height: var(--full-height);
height: max(100vh, var(--full-height, 0px));
}
.m-glass {