fix: resolve iOS PWA bottom space and keyboard zoom issues

- pwa.css: body::after now uses var(--glass-bg) matching the nav's glass
  background exactly; z-index lowered to z-nav-1 so the nav renders
  on top in the overlap area (safe-area padding), removing the visible
  color mismatch that appeared as empty space
- router.js: add iOS focusin/focusout handlers that temporarily set
  maximum-scale=1 on input focus to prevent WKWebView auto-zoom;
  restores original viewport content 150ms after blur so manual
  zoom remains available for accessibility
This commit is contained in:
Ulas
2026-04-16 15:35:03 +02:00
parent 5bd80b1333
commit 66816a4f88
2 changed files with 41 additions and 6 deletions
+32
View File
@@ -589,6 +589,38 @@ if (window.visualViewport) {
});
}
// --------------------------------------------------------
// iOS PWA: Viewport-Zoom bei Tastatur-Erscheinen verhindern.
// iOS Safari/WKWebView zoomt ins Layout wenn ein Formularfeld fokussiert wird
// und stellt den Zoom nach Tastatur-Schliessen im Standalone-Modus nicht
// automatisch zurück → Menüpunkte verschwinden aus dem sichtbaren Bereich.
//
// Fix: maximum-scale=1 während des Focus setzt (verhindert Zoom),
// danach original Wert wiederherstellen (erhält manuelle Zoom-Möglichkeit
// für Barrierefreiheit). Nur auf iOS-Geräten aktiv.
// --------------------------------------------------------
if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
const metaViewport = document.querySelector('meta[name="viewport"]');
if (metaViewport) {
const originalContent = metaViewport.getAttribute('content');
const noZoomContent = originalContent.replace(/maximum-scale=\d+/, 'maximum-scale=1');
document.addEventListener('focusin', ({ target }) => {
if (['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName)) {
metaViewport.setAttribute('content', noZoomContent);
}
});
document.addEventListener('focusout', ({ target }) => {
if (['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName)) {
// Kurze Verzögerung: iOS braucht ~150ms um Layout nach Tastatur-
// Schliessen wiederherzustellen, bevor scale zurückgesetzt wird.
setTimeout(() => metaViewport.setAttribute('content', originalContent), 150);
}
});
}
}
// --------------------------------------------------------
// Initialisierung
// --------------------------------------------------------