Skip to content

console: pin the page behind an open dialog so iOS can't scroll a drawer away - #463

Merged
drudge merged 1 commit into
mainfrom
claude/ios-insights-drawer-height-7mv486
Oct 19, 2026
Merged

drudge merged 1 commit into
mainfrom
claude/ios-insights-drawer-height-7mv486

Conversation

@drudge

@drudge drudge commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

Requested by Nick · project thread

Before: on an iPhone (seen in the Home Screen app), an Insights device drawer could end up floating partway up the screen, its top cut off, with the finding rows showing undimmed below its footer.

After: the drawer stays anchored to the bottom of the screen with the backdrop covering the page.

The drawer and its backdrop both moved up together, by about 310px. That means the page behind the modal scrolled. overflow: hidden on the root doesn't stop iOS from scrolling the document, and when it does, things fixed to a viewport that iOS no longer moves slide off with the page. The touch guard from #441 refuses most of those scrolls, but it can only cancel a touch move before the browser starts scrolling, and it can't stop a fling, a focus scroll, or a second finger.

How

  • app.css: while a dialog is open, html.modal-scroll-lock body is position: fixed at top: var(--modal-scroll-top). The page looks exactly where it was, and the document has nothing left to scroll.
  • app.js: the observer that already saved and restored the page position around a modal now also sets that class and offset as the first dialog opens and clears them before scrolling back as the last one closes. The phone header's hide-on-scroll ignores the scroll the lock causes, so it comes back as it was.
  • modal-scroll-lock.cjs: checks that opening a modal leaves the page in place, pins the body, leaves the document nothing to scroll, and that closing unpins and restores the position.

Screenshots

An Insights device drawer opened from about 900px down the page. Headless Chromium doesn't scroll a frozen root the way iOS does, so before and after look the same (only the demo's times differ). They show the lock doesn't move the page or the drawer. The fix itself needs checking on an iPhone.

Before (main) After
Laptop
Phone

Checks

  • go test ./internal/web/... passes.
  • The whole browser suite passes locally except LogSearch and NavSwipe, which fail the same way on main in this container.

@drudge drudge self-assigned this Oct 15, 2026
@drudge
drudge marked this pull request as ready for review October 15, 2026 23:38

@drudge drudge left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review by Blake, posted by Whiteface: APPROVE.

Body is pinned fixed at -scrollY via a root class driven by the existing dialog[open] MutationObserver and restored on close; header auto-hide is guarded; regression script extended and Browser regression CI green.

Non-blocking: inset-inline: 0 means horizontal scroll isn't pinned (only matters under 320px viewports).

@drudge
drudge merged commit 00e92e1 into main Oct 19, 2026
4 checks passed
@drudge drudge mentioned this pull request Oct 19, 2026
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