fix: comprehensive iOS Safari safe area fix
All checks were successful
build-website / build (push) Successful in 1m42s

- Removed Tailwind @apply from body to prevent default backgrounds
- Forced transparent backgrounds on all containers with !important
- Switched from position:fixed to position:absolute (iOS Safari bug workaround)
- Added autoplay fallback for iOS user interaction requirement
- Ensured video extends into safe area with negative top positioning
This commit is contained in:
Matt
2025-09-25 16:24:20 +02:00
parent 2fedc094d8
commit f534a4bba3
2 changed files with 32 additions and 13 deletions

View File

@@ -7,8 +7,13 @@
html, body { html, body {
margin: 0; margin: 0;
padding: 0; padding: 0;
/* Transparent background to allow video in safe area */ /* Force transparent background to allow video in safe area */
background: transparent; background: transparent !important;
}
/* Ensure all wrapper elements are also transparent */
#__nuxt, .app-layout, main {
background: transparent !important;
} }
/* Smooth Scroll Behavior and iOS Overscroll Prevention */ /* Smooth Scroll Behavior and iOS Overscroll Prevention */
@@ -143,7 +148,11 @@ body {
/* Typography */ /* Typography */
@layer base { @layer base {
body { body {
@apply font-sans text-gray-800 antialiased; /* Removed @apply to prevent Tailwind from adding default backgrounds */
font-family: Inter, sans-serif;
color: #1f2937;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {

View File

@@ -168,29 +168,39 @@ onMounted(() => {
videoLoaded.value = true videoLoaded.value = true
} }
}, 1500) }, 1500)
// iOS autoplay fallback - play on first user interaction
const tryPlay = () => {
if (videoElement.value?.paused) {
videoElement.value.play().catch(() => {
// Silently fail if autoplay is still blocked
})
}
}
// Listen for any user interaction to trigger video play
window.addEventListener('pointerdown', tryPlay, { once: true })
window.addEventListener('touchstart', tryPlay, { once: true })
}) })
</script> </script>
<style scoped> <style scoped>
/* Hero video container using standard safe-area-inset-top for iOS Safari */ /* Hero video container - absolute positioning to extend into safe areas */
.hero-video-container { .hero-video-container {
position: fixed; /* Use fixed to escape ALL containing blocks and position relative to viewport */ position: absolute; /* Use absolute to avoid iOS Safari position:fixed bugs */
left: 0; /* Extend ABOVE viewport to fill safe area */
right: 0;
width: 100vw;
/* Use standard safe-area-inset-top */
/* Pull up by the safe area to extend under notch */
top: calc(-1 * env(safe-area-inset-top, 0px)); top: calc(-1 * env(safe-area-inset-top, 0px));
/* Extend height to compensate */ left: 0;
width: 100vw;
/* Increase height to include safe area */
height: calc(100vh + env(safe-area-inset-top, 0px)); height: calc(100vh + env(safe-area-inset-top, 0px));
z-index: 0; /* Base layer for video */ z-index: 0; /* Base layer for video */
pointer-events: none; pointer-events: none;
overflow: hidden; /* Keep video content clipped */
/* Apply parallax transform using CSS variable - delayed to prevent autoplay issues */ /* Apply parallax transform using CSS variable - delayed to prevent autoplay issues */
transform: translateY(var(--parallax-offset, 0px)); transform: translateY(var(--parallax-offset, 0px));
will-change: transform; /* Optimization hint */ will-change: transform; /* Optimization hint */
/* Initial state for autoplay compatibility */ /* Initial state for autoplay compatibility */
transition: transform 0.1s ease-out; transition: transform 0.1s ease-out;
/* Removed contain property to allow extension into safe area */
} }
/* iOS Safari safe area extension - use env() only, no hardcoded fallbacks */ /* iOS Safari safe area extension - use env() only, no hardcoded fallbacks */
@@ -268,7 +278,7 @@ onMounted(() => {
} }
.hero-content { .hero-content {
position: fixed; /* Use fixed to match video container positioning */ position: absolute; /* Use absolute to match video container positioning */
top: 0; /* Start at viewport top */ top: 0; /* Start at viewport top */
left: 0; left: 0;
right: 0; right: 0;