From 685f9d8369439620c8eea1d86168551a555f4c2b Mon Sep 17 00:00:00 2001 From: Florent Tapponnier Date: Tue, 2 Jun 2026 13:53:51 +0200 Subject: [PATCH] fix: drop overflow-x clip from body so position: fixed sticks on WKWebView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User reports a 1-2 px gap at the top of the header in Telegram in-app Safari that lets page content peek through during scroll. Root cause: body had overflow-x: clip (PR #242 safety net) and WebKit treats clip on body as creating a containing block for position: fixed descendants. The fixed header was then anchored to body's top edge, not the viewport, and momentum scroll desynced it from the URL-bar animation, producing the visible slit. Move the overflow-x clip safety net to only.
and
already carry overflow-x-clip (PR #244) so page-level horizontal overflow remains contained without needing it on body. Drop the translate3d hint on the header — it was paired with the clip workaround and is not needed once fixed positions cleanly against the viewport. --- src/app/globals.css | 18 +++++++----------- src/app/layout.tsx | 8 ++++---- src/components/site-header.tsx | 14 ++++++-------- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index 3d988d98..6a6bda59 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -329,16 +329,12 @@ html { text-size-adjust: 100%; } -/* Safety net: clip any rogue horizontal overflow on BOTH html and body. - iOS Safari + Telegram WKWebView sometimes ignore `overflow-x: clip` - on alone and still let a wide child push the page past 100vw. - Applying it to body too — plus capping body width at 100vw — covers - the WebView edge cases. `clip` (not `hidden`) avoids creating a - scroll container, so position: sticky on the header keeps working. */ -html, -body { +/* Safety net: clip horizontal overflow at the html (viewport) level only. + Do NOT apply overflow-x: clip to — WebKit treats clip on + as creating a containing block for position: fixed descendants, which + detaches the sticky/fixed header from the viewport and lets a 1-2 px + gap appear at the top during momentum scroll in Telegram WKWebView. + Per-component clipping (main, article) catches anything html misses. */ +html { overflow-x: clip; } -body { - max-width: 100vw; -} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 30f87ac0..6ae2e892 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -127,10 +127,10 @@ export default function RootLayout({ {/* grid (not flex) so position: sticky on works reliably on iOS Safari — sticky inside a flex column has known quirks. - w-full + overflow-x-clip on the body guarantees no descendant can - push the page past the viewport, even when WKWebView (Telegram in-app - browser) ignores the html-level safety net in globals.css. */} - + Do NOT add overflow-x clip here — WebKit treats it as creating a + containing block for position: fixed descendants and the header + ends up scrolling with the body. Clip is on html + main + article. */} +