Skip to content

fix(ui): stop header shifting on scrollbar gutter changes#27

Merged
fullstackjam merged 1 commit into
mainfrom
fix/header-scrollbar-jitter
Jun 27, 2026
Merged

fix(ui): stop header shifting on scrollbar gutter changes#27
fullstackjam merged 1 commit into
mainfrom
fix/header-scrollbar-jitter

Conversation

@fullstackjam

Copy link
Copy Markdown
Member

Summary

The site header is a viewport-centered, position: fixed element shared across every route (src/routes/+layout.svelte). A centered fixed element only moves when the viewport width changes — and the vertical scrollbar (~15px) appearing on some pages but not others did exactly that, re-centering the header by half the scrollbar width (~7.5px) on every navigation between a scrolling and a non-scrolling page (e.g. /explore/docs). That's the visible "jitter."

Fix: reserve the scrollbar gutter on the root element so its space is constant regardless of whether a route scrolls.

:global(html) { scrollbar-gutter: stable; }

scrollbar-gutter: stable no-ops on macOS overlay scrollbars (which never took layout space and never shifted), so it only reserves space for the classic / always-on scrollbars that actually caused the jitter — no permanent empty track for trackpad users.

Test plan

  • Reproduced in-browser (Playwright, 1280px wide): isolating the scrollbar as the only variable, header left = 52.5px with scrollbar vs 60px without → 7.5px shift.
  • After the fix, the same isolation test reports header left = 52.5px in both states → 0px shift.
  • computedStyle(html).scrollbarGutter === 'stable' confirmed applied.

🤖 Generated with Claude Code

The site header is a viewport-centered, fixed element shared across all
routes. A centered fixed element only moves when the viewport width changes,
and the vertical scrollbar (~15px) appearing on some pages but not others did
exactly that — re-centering the header by half the scrollbar width (~7.5px)
on every navigation between a scrolling and a non-scrolling page.

Reserve the scrollbar gutter on the root element so its space is constant
regardless of whether a route scrolls. scrollbar-gutter: stable no-ops on
overlay scrollbars (which never shifted), so it only affects the classic /
always-on scrollbars that caused the jitter.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@fullstackjam fullstackjam merged commit a2d326d into main Jun 27, 2026
8 checks passed
@fullstackjam fullstackjam deleted the fix/header-scrollbar-jitter branch June 27, 2026 06:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant