From 86401b91fc8e7b25306c17be185ad90f80aec180 Mon Sep 17 00:00:00 2001 From: matt Date: Fri, 19 Sep 2025 10:36:14 +0200 Subject: [PATCH] Fix iPhone Safari viewport to fill entire screen - Add viewport-fit=cover to meta tag for safe area extension - Implement iOS-specific height handling with -webkit-fill-available - Use dynamic viewport height (100dvh) for proper mobile behavior - Extend video container beyond safe areas with negative positioning - Add safe area padding with env() variables for content positioning - Include mobile-specific @supports queries for better compatibility This ensures the hero section fills the entire iPhone viewport from top to bottom, extending behind the status bar and home indicator while keeping content readable within safe areas. --- apps/website/assets/css/main.css | 30 +++++++++++++++++++++ apps/website/assets/css/voyage-layout.css | 33 +++++++++++++++++++---- apps/website/nuxt.config.ts | 2 +- 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/apps/website/assets/css/main.css b/apps/website/assets/css/main.css index 69c05fe..6351add 100644 --- a/apps/website/assets/css/main.css +++ b/apps/website/assets/css/main.css @@ -9,6 +9,7 @@ html { overscroll-behavior-y: contain; -webkit-overflow-scrolling: touch; /* Proper iOS viewport handling */ + height: 100%; height: -webkit-fill-available; /* Prevent horizontal scrolling */ overflow-x: hidden !important; @@ -28,6 +29,35 @@ body { position: relative; } +/* iOS-specific viewport handling */ +@supports (-webkit-touch-callout: none) { + /* iOS Safari */ + .hero-voyage { + height: 100vh; + height: -webkit-fill-available; + height: 100dvh; + } + + .hero-video-container { + height: calc(100vh + env(safe-area-inset-top) + env(safe-area-inset-bottom)); + height: calc(100dvh + env(safe-area-inset-top) + env(safe-area-inset-bottom)); + } +} + +/* Handle dynamic viewport on mobile browsers */ +@media screen and (max-width: 768px) { + @supports (height: 100dvh) { + .hero-voyage { + height: 100dvh; + min-height: 100dvh; + } + + .hero-content { + min-height: 100dvh; + } + } +} + /* Accessibility: Reduced Motion */ @media (prefers-reduced-motion: reduce) { html { diff --git a/apps/website/assets/css/voyage-layout.css b/apps/website/assets/css/voyage-layout.css index 7575a27..b6ebb10 100644 --- a/apps/website/assets/css/voyage-layout.css +++ b/apps/website/assets/css/voyage-layout.css @@ -398,7 +398,11 @@ html { /* Hero Section */ .hero-voyage { position: relative; - height: 100dvh; + height: 100vh; /* Fallback for browsers that don't support newer units */ + height: -webkit-fill-available; /* iOS Safari */ + height: 100dvh; /* Dynamic viewport height */ + min-height: 100vh; + min-height: -webkit-fill-available; min-height: 100dvh; overflow: hidden; overscroll-behavior-y: none; @@ -406,13 +410,20 @@ html { overflow-x: hidden !important; max-width: 100vw !important; contain: layout; + /* Extend into safe areas on iOS */ + padding-top: env(safe-area-inset-top); + padding-bottom: env(safe-area-inset-bottom); } .hero-video-container { position: absolute; - inset: 0; + /* Extend beyond safe areas */ + top: calc(-1 * env(safe-area-inset-top)); + left: 0; + right: 0; + bottom: calc(-1 * env(safe-area-inset-bottom)); width: 100%; - height: 100%; + height: calc(100% + env(safe-area-inset-top) + env(safe-area-inset-bottom)); overflow: hidden; z-index: 1; } @@ -1659,21 +1670,33 @@ html { @media (max-width: 768px) { .hero-voyage { padding: 0; + /* iOS-specific height handling */ + height: 100vh; + height: -webkit-fill-available; + height: 100dvh; + min-height: 100vh; + min-height: -webkit-fill-available; min-height: 100dvh; - height: 100dvh; - height: 100dvh; + /* Extend into safe areas */ + padding-top: env(safe-area-inset-top); + padding-bottom: env(safe-area-inset-bottom); overflow-x: hidden !important; max-width: 100vw !important; } .hero-content { + /* Adjust padding to account for safe areas */ padding: clamp(1rem, 4vw, 2rem); + padding-top: max(env(safe-area-inset-top), clamp(1rem, 4vw, 2rem)); + padding-bottom: max(env(safe-area-inset-bottom), clamp(1rem, 4vw, 2rem)); overflow-x: hidden; width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; + min-height: 100vh; + min-height: -webkit-fill-available; min-height: 100dvh; } diff --git a/apps/website/nuxt.config.ts b/apps/website/nuxt.config.ts index b510180..7c9eb1e 100644 --- a/apps/website/nuxt.config.ts +++ b/apps/website/nuxt.config.ts @@ -118,7 +118,7 @@ export default defineNuxtConfig({ title: 'Harbor Smith - Personalized Service Maintenance For Your Boat', meta: [ { charset: 'utf-8' }, - { name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=5, user-scalable=yes' }, + { name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=5, user-scalable=yes, viewport-fit=cover' }, { name: 'description', content: 'Professional boat maintenance services in San Francisco Bay. Mobile service at your dock.' }, { name: 'format-detection', content: 'telephone=no' } ],