From 5de43236c3d8d0f6d0e9d6dd6b8a125f59f18ac1 Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 25 Sep 2025 15:42:39 +0200 Subject: [PATCH] fix: resolve iOS Safari safe area and parallax issues - Add transform rule to video container for parallax functionality - Change hero-content to absolute positioning to extend into safe areas - Remove hardcoded fallback values, use only env() functions - Delete conflicting mobile CSS overrides with !important declarations - Fix CSS cascade issues that prevented proper safe area rendering These changes ensure the video parallax effect works correctly and content properly extends into iOS safe areas (notch/Dynamic Island). --- apps/website/assets/css/voyage-layout.css | 71 ++++------------------- apps/website/components/HeroSection.vue | 31 +++++----- 2 files changed, 26 insertions(+), 76 deletions(-) diff --git a/apps/website/assets/css/voyage-layout.css b/apps/website/assets/css/voyage-layout.css index 847557a..8ce381a 100644 --- a/apps/website/assets/css/voyage-layout.css +++ b/apps/website/assets/css/voyage-layout.css @@ -507,16 +507,18 @@ html { } .hero-content { - position: relative; + position: absolute; /* Changed to absolute for safe area extension */ + top: 0; /* Start at viewport top */ + left: 0; + right: 0; z-index: 10; - height: 100%; - min-height: 100vh; /* Fallback for browsers without dvh support */ - min-height: 100dvh; /* Dynamic viewport height for Chrome mobile */ + height: 100vh; width: 100%; - display: grid; - grid-template-rows: 1fr auto; + display: flex; + flex-direction: column; align-items: center; - justify-items: center; + justify-content: center; + padding-top: env(safe-area-inset-top, 0px); /* Only safe area, no additions */ text-align: center; /* Safari-compatible safe area padding with fallbacks */ padding-top: calc(max(env(safe-area-inset-top), 44px) + clamp(2rem, 8vh, 5rem)); @@ -533,13 +535,7 @@ html { } } -/* iOS-specific padding for hero content */ -@supports (-webkit-touch-callout: none) { - .hero-content { - /* Allow content to extend into safe area, don't push it down */ - padding-top: clamp(2rem, 8vh, 5rem); /* Normal padding only, no safe area addition */ - } -} +/* iOS-specific - content already positioned absolutely with safe area padding */ .hero-main { width: min(720px, 100%); @@ -1763,52 +1759,7 @@ html { max-width: 100vw !important; } - /* iOS-specific video extension into safe area */ - @supports (-webkit-touch-callout: none) { - /* Only iOS Safari */ - .hero-video-container { - position: fixed !important; - left: 0; - right: 0; - /* Extend beyond safe area to ensure coverage on iOS */ - top: calc(-1 * (env(safe-area-inset-top, 0) + 50px)) !important; - width: 100vw; - height: calc(100lvh + env(safe-area-inset-top, 0) + 50px) !important; - z-index: -1; - pointer-events: none; - background: #ffffff; /* White fallback if video doesn't load */ - } - - /* Extra insurance for iOS 15-26 */ - @supports (height: 100dvh) { - .hero-video-container { - height: calc(100dvh + env(safe-area-inset-top, 0) + 50px) !important; - } - } - - /* iOS-specific video sizing */ - .hero-video { - width: 100%; - height: 100%; - object-fit: cover; - object-position: center top; /* Align to top for better notch coverage */ - } - } - - /* Non-iOS mobile devices keep normal positioning */ - @supports not (-webkit-touch-callout: none) { - .hero-video-container { - position: fixed !important; - left: 0; - right: 0; - top: 0; /* Normal positioning for Android/other mobile */ - width: 100vw; - height: 100vh; - z-index: -1; - pointer-events: none; - background: #ffffff; - } - } + /* Removed conflicting mobile overrides - handled in HeroSection.vue component */ .hero-content { /* Adjust padding to allow content into safe areas */ diff --git a/apps/website/components/HeroSection.vue b/apps/website/components/HeroSection.vue index 135e0cc..5351c6c 100644 --- a/apps/website/components/HeroSection.vue +++ b/apps/website/components/HeroSection.vue @@ -185,27 +185,18 @@ onMounted(() => { height: calc(100vh + env(safe-area-inset-top, 0px)); z-index: 0; /* Base layer for video */ pointer-events: none; - /* iOS Safari rendering optimizations */ - -webkit-transform: translate3d(0, 0, 0); /* Force GPU layer */ - transform: translateZ(0); /* Hardware acceleration */ + /* Apply parallax transform using CSS variable */ + transform: translateY(var(--parallax-offset, 0px)); will-change: transform; /* Optimization hint */ /* Removed contain property to allow extension into safe area */ } -/* iOS Safari safe area extension with proper env() usage */ +/* iOS Safari safe area extension - use env() only, no hardcoded fallbacks */ @supports (-webkit-touch-callout: none) { .hero-video-container { - /* Use max() to provide fallback when env() returns 0 */ - top: calc(-1 * max(env(safe-area-inset-top), 59px)); - height: calc(100vh + max(env(safe-area-inset-top), 59px)); - } - - /* Older iPhones with smaller notch */ - @media screen and (max-height: 812px) { - .hero-video-container { - top: calc(-1 * max(env(safe-area-inset-top), 44px)); - height: calc(100vh + max(env(safe-area-inset-top), 44px)); - } + /* Use env() directly without hardcoded fallbacks */ + top: calc(-1 * env(safe-area-inset-top, 0px)); + height: calc(100vh + env(safe-area-inset-top, 0px)); } } @@ -275,8 +266,16 @@ onMounted(() => { } .hero-content { - position: relative; + position: absolute; /* Changed from relative to occupy safe areas */ + top: 0; /* Start at viewport top */ + left: 0; + right: 0; + width: 100%; + height: 100vh; z-index: 10; /* Ensure content is above video */ + display: flex; + flex-direction: column; + padding-top: env(safe-area-inset-top, 0px); /* Safe area padding */ } .hero-main {