diff --git a/frontend/index.css b/frontend/index.css index 87be6ce..e6edb7e 100644 --- a/frontend/index.css +++ b/frontend/index.css @@ -152,3 +152,14 @@ body div.sidebar { height: 100%; contain: layout style paint; } + +/* Hidden cached views: use visibility+size collapse instead of + display:none so scroll containers preserve their scrollTop. + display:none discards scroll state in WebKitGTK. */ +.main-panel > .view-hidden { + visibility: hidden !important; + height: 0 !important; + overflow: hidden !important; + pointer-events: none !important; + contain: strict !important; +} diff --git a/frontend/index.ts b/frontend/index.ts index 223bd43..cb39c47 100644 --- a/frontend/index.ts +++ b/frontend/index.ts @@ -92,15 +92,16 @@ document.addEventListener('navigate', (e: Event) => { target = document.createElement(VIEW_TAGS[view]); viewCache.set(view, target); // Start hidden — we'll un-hide below - target.style.display = 'none'; + target.classList.add('view-hidden'); mainContent.appendChild(target); } - // Hide current, show target + // Hide current, show target. Uses CSS class instead of + // display:none so scroll containers preserve scrollTop. if (currentViewEl && currentViewEl !== target) { - currentViewEl.style.display = 'none'; + currentViewEl.classList.add('view-hidden'); } - target.style.display = ''; + target.classList.remove('view-hidden'); currentViewEl = target; return; } @@ -108,7 +109,7 @@ document.addEventListener('navigate', (e: Event) => { // --- Detail (ephemeral) views ----------------------------------------- // Hide the current primary view if (currentViewEl) { - currentViewEl.style.display = 'none'; + currentViewEl.classList.add('view-hidden'); } // Remove any prior detail element if (currentDetailEl) {