Use window.innerHeight for mobile viewport height on Chrome Android

Set --app-height CSS custom property from window.innerHeight via JS,
which is the only reliable way to get the actual visible viewport on
Chrome Android. Falls back to 100vh if JS hasn't loaded.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
adlee-was-taken 2026-02-22 14:28:58 -05:00
parent 097f241c6f
commit 7dc27fe882
2 changed files with 16 additions and 9 deletions

View File

@ -90,10 +90,20 @@ class GolfGame {
} }
initMobileDetection() { initMobileDetection() {
// Set --app-height custom property to actual visible viewport height.
// This works around Chrome Android's 100vh bug where vh includes the
// space behind the dynamic URL bar.
const setAppHeight = () => {
document.documentElement.style.setProperty('--app-height', `${window.innerHeight}px`);
};
window.addEventListener('resize', setAppHeight);
setAppHeight();
const mql = window.matchMedia('(max-width: 500px) and (orientation: portrait)'); const mql = window.matchMedia('(max-width: 500px) and (orientation: portrait)');
const update = (e) => { const update = (e) => {
this.isMobile = e.matches; this.isMobile = e.matches;
document.body.classList.toggle('mobile-portrait', e.matches); document.body.classList.toggle('mobile-portrait', e.matches);
setAppHeight();
// Close any open drawers on layout change // Close any open drawers on layout change
if (!e.matches) { if (!e.matches) {
this.closeDrawers(); this.closeDrawers();

View File

@ -4906,9 +4906,7 @@ body.screen-shake {
} }
body.mobile-portrait { body.mobile-portrait {
height: 100vh; height: var(--app-height, 100vh);
height: -webkit-fill-available;
height: 100dvh;
overflow: hidden; overflow: hidden;
overscroll-behavior: contain; overscroll-behavior: contain;
touch-action: manipulation; touch-action: manipulation;
@ -4916,19 +4914,18 @@ body.mobile-portrait {
body.mobile-portrait #app { body.mobile-portrait #app {
padding: 0; padding: 0;
height: 100%; height: var(--app-height, 100vh);
overflow: hidden; overflow: hidden;
} }
/* --- Mobile: Game screen fills viewport --- */ /* --- Mobile: Game screen fills viewport --- */
/* IMPORTANT: Must include .active to avoid overriding .screen { display: none } */ /* IMPORTANT: Must include .active to avoid overriding .screen { display: none } */
body.mobile-portrait #game-screen.active { body.mobile-portrait #game-screen.active {
position: fixed; height: var(--app-height, 100vh);
top: 0; max-height: var(--app-height, 100vh);
left: 0;
right: 0;
bottom: 0;
overflow: hidden; overflow: hidden;
margin-left: 0;
width: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }