fix(docsite): pin the hero with sticky rails, drop the overscroll suppression - #5480
Draft
AKnassa wants to merge 1 commit into
Draft
fix(docsite): pin the hero with sticky rails, drop the overscroll suppression#5480AKnassa wants to merge 1 commit into
AKnassa wants to merge 1 commit into
Conversation
Contain the desktop-pinned hero layers so the app-global `overscroll-behavior-y: none` can be deleted outright instead of gated to desktop widths: macOS trackpads get their native rubber-band back. A `fixed` layer is not part of the document, so when the document rubber-bands past its own edge the layer sits in the exposed gap. A `sticky` layer lifts with the document and cannot paint past its containing block. Each pinned layer (aurora backdrop, overlap cards, hero text) now rides its own `absolute; inset: 0` rail, a direct child of heroScope spanning hero band + showcase and placed ahead of the showcase overlay, as a `position: sticky` box at >=1024px. Centering moves from `left: 50%` + `translateX(-50%)` to auto margins inside the full-width rail, and the 1200px box is capped to the rail's width rather than 100vw: with a classic scrollbar 100vw is wider than the rail, which zeroes the auto margins and shoves the box left. A rail inside the 760px band alone would release the layer after ~48px, which is why the rails span the showcase too. HeroReelProvider is context-only now; its hover/focus/touch surface is the new HeroReelSwipeArea, which page.tsx uses as the hero text's rail so the band still pauses the reel and the mobile collage still swipes. Also records on LayoutContent why `overflow: clip` must stay `clip`: `hidden` or `auto` there would silently un-pin the landing page. A source-invariant test (the docsite suite is node-only) guards the rule's absence, the three layers never going back to `fixed`, the rails' order and containment, and the AppShell/LayoutContent links that keep the main area a non-scroll container. Verified against untouched main with Playwright + pixelmatch at six viewports x ten scroll offsets: 0 px at the default threshold, identical layer geometry, `overscroll-behavior-y: auto` everywhere, no fixed element reaching the viewport bottom (was 2-3), 11/11 hover/focus/swipe checks passing on both trees, resize-while-scrolled and theme-swap mid-scroll 0 px. Safari and a real rubber-band are not verified here. Step 2 of facebook#5392. Fixes facebook#5470. Supersedes the zero-height-pin approach in facebook#5431 and folds in the backdropGlow comment correction from facebook#5467.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
github-actions
Bot
requested review from
cvkxx,
ernestt,
kentonquatman and
rubyycheung
August 25, 2026 04:50
Contributor
PR Analysis Report📚 Storybook PreviewView Storybook for this PR 🧪 Sandbox PreviewView Sandbox for this PR Modified ComponentsLayout (@astryxdesign/core) · View in Storybook
Bundle Size Summary
Accessibility AuditStatus: 1 accessibility violation(s) found — 1 serious. Layout - 1 issue(s)
Generated by PR Enrichment workflow | Storybook | Sandbox | View full report |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Step 2 of #5392. Fixes #5470.
What this does
Keeps the home page hero pinned exactly as it is today, but without the CSS rule that switched off the browser's native overscroll. On a Mac trackpad the page rubber-bands again at the top and bottom, like every other page on the web. Nothing changes visually.
Why
The hero's three pinned layers (the aurora glow, the floating cards and the headline block) were
position: fixed. A fixed layer is glued to the screen rather than to the page, so when the page rubber-bands past its own end the layer sits in the gap that opens up. #3032 hid that by turning overscroll off for the whole site, and #5415 narrowed the rule to desktop widths to give mobile its pull-to-refresh back. This finishes the job: the layers are nowposition: stickyinside full-height rails, so they lift with the page and physically cannot paint past its end. That is structural, which is why the rule can be deleted instead of narrowed further.What changed
position: absolute; inset: 0box that is a direct child ofheroScope, spans the hero band and the showcase, and sits ahead of the showcase overlay so tree order still equals paint order (backdrop, cards, hero text, then the showcase covering them). A rail inside the 760px band alone releases its layer after about 48px, which is the trap the issue calls out.backdropGlow, the cardsstageandheroContentgofixed->sticky; top: var(--appshell-header-height)at 1024px and up. Narrow widths are untouched: the glow stays absolute and the hero text stays in flow.left: 50%+translateX(-50%)to auto margins in the full-width rail (on a sticky boxleftis an inset, not an offset). The 1200px box is capped to the rail's width rather than100vw: with a classic scrollbar100vwis wider than the rail, which zeroes the auto margins and shoves the box left.HeroReelProviderrenders no DOM any more. Its hover / focus / touch surface is the newHeroReelSwipeArea, whichpage.tsxuses as the hero text's rail, so the band and its gutters still pause the reel and the phone collage still swipes.HeroReelCardsis split intoHeroReelBackdrop(fills + glow) andHeroReelCards(stage).@media (min-width: 1024px) { html { overscroll-behavior-y: none } }block is deleted fromglobals.css.LayoutContent'soverflow: cliprecords why it must stayclip:hiddenorautothere would silently un-pin the landing page (the issue asked for this).home-hero-overscroll.test.ts. The docsite suite is node-only with StyleX untransformed, so these are source invariants in the shape ofcomponent-preview-theme.test.ts:globals.cssnever suppresses overscroll at any width; none of the three layers is everfixedin any media arm; the rails are bounded byheroScopeand precede the showcase; the boxes are sized against the rail, not100vw; and the AppShell / LayoutContent links that keep the main area a non-scroll container (overflow: clip,isScrollable={isFill}, the landing layout'sheight="auto") hold. It is red onmaintoday, and 11 single-line mutations (afixedbehind a trailing comment, double quotes, a computed[BREAKPOINT]key, anoverflowYlonghand,isScrollableunconditional,height="fill", the width back to100vw,heroScopestatic, a rail moved after the showcase,overscroll-behavior: contain, an uppercase rule) each turn it red again.How to see it
Nothing should look different; that is the point. Run the docsite with the canary banner off so the header is the production 48px (
NEXT_PUBLIC_DOCS_TARGET=latest pnpm -F @astryxdesign/docsite dev), open the home page on a Mac and rubber-band at the bottom: the page bounces and the footer stays clean. The Vercel preview on this PR shows the same page.Measured against an untouched
maincheckout with Playwright + pixelmatch, both served with the banner hidden,prefers-reduced-motion: reduceso the reel holds its first slide, and transitions frozen, at ten scroll offsets per viewport (0, 100, 200, 400, 712, 760, 800, 1400, 2200, max):mainoverscroll-behavior-ynone->autonone->autonone->autonone->autoauto->autoauto->autoLayer geometry matches
fixedat every offset (hero text at y=48 and 712px tall, glow and stage at x=40 and 1200px wide at 1280) until max scroll, where sticky releases behind the opaque showcase. Document height is unchanged (3540px).elementFromPointon the "Get started" button still returns the button.Also checked on both trees: hover in the gutter, on the CTA and over the pinned hero while scrolled pauses the reel, hover on the showcase does not, keyboard focus on a dot pauses and blur resumes, a phone swipe steps the reel left and right and a vertical drag does not (11 checks, identical results before and after); resize while scrolled (1280 -> 1440 -> 1100 at scroll 400) and a theme swap mid-scroll with transitions running, 0 pixels differing; and a forced 15px classic scrollbar, where the old
fixedbox sat at x=-7.5 overflowing both sides and the new one sits centered inside the rail.pnpm -F @astryxdesign/docsite test(27 files, 413 tests),tsc --noEmit, strict eslint andpnpm lint:strict(0 errors) are green.Not verified here
Safari and WebKit, and a real rubber-band gesture, which cannot be driven headlessly. That is the careful visual pass the issue budgets for.
Related
backdropGlowcomment's causal chain; that comment is rewritten here with the same correction, so the two overlap if both land.