fix(web): stabilize chat scrolling and mobile alignment - #1278
Conversation
There was a problem hiding this comment.
Findings
-
[Major] Global document locking can make login/binding controls unreachable on short viewports —
html,body, and#rootnow hide overflow, butLoginPromptis a full-height centered layout without an inner scroll owner. In landscape or after the mobile keyboard shrinks the viewport, overflow is clipped instead of scrollable. Evidence:web/src/index.css:296,web/src/index.css:308,web/src/components/LoginPrompt.tsx:116.
Suggested fix:html, body { overflow-x: hidden; overflow-y: auto; } #root { overflow: visible; } html:has(.chat-scroll-y), body:has(.chat-scroll-y), html:has(.chat-scroll-y) #root { overflow: hidden; }
-
[Minor] Touch devices with overlay scrollbars lose almost all chat side padding —
scrollbar-gutterreserves layout space only for classic scrollbars, while the content padding is reduced from0.75remto0.125remfor every coarse pointer. Common mobile overlay-scrollbar layouts therefore render messages about 2px from both edges. Evidence:web/src/index.css:321,web/src/index.css:325,web/src/components/AssistantChat/HappyThread.tsx:1420.
Suggested fix:@media (hover: none) and (pointer: coarse) { .chat-scroll-y { scrollbar-gutter: stable both-edges; } /* Keep the existing p-3 fallback when no physical gutter is reserved. */ }
Summary
Review mode: initial
Two issues found: document-level overflow containment is not safe for the non-scrollable authentication shell, and the gutter compensation does not preserve padding on overlay-scrollbar mobile browsers.
Testing
Not run (review automation; PR code was not executed). Add browser coverage for a short/landscape login viewport and a touch viewport using overlay scrollbars.
HAPI Bot
| * example while an attachment image is being measured) cannot create a | ||
| * second, stale page scrollbar. | ||
| */ | ||
| overflow: hidden; |
There was a problem hiding this comment.
[MAJOR] Global document locking clips the authentication shell on short viewports
This applies overflow: hidden to html/body, and the new #root rule also hides overflow. LoginPrompt (web/src/components/LoginPrompt.tsx:116) is a full-height centered container without .app-scroll-y; when its form plus footer exceeds the visual viewport (landscape phone or opened keyboard), the overflow is unreachable. Scope the lock to the chat route, or give every pre-auth screen an explicit scroll owner.
Suggested fix:
html,
body {
overflow-x: hidden;
overflow-y: auto;
}
#root {
overflow: visible;
}
html:has(.chat-scroll-y),
body:has(.chat-scroll-y),
html:has(.chat-scroll-y) #root {
overflow: hidden;
}There was a problem hiding this comment.
Fixed in 9dd77d7. I restored the existing document scrolling behavior for non-chat routes and now apply overflow containment only while a .chat-scroll-y viewport is present, so short login/binding viewports remain reachable.
| } | ||
|
|
||
| .chat-scroll-content { | ||
| padding-inline: 0.125rem; |
There was a problem hiding this comment.
[MINOR] Preserve padding when the touch scrollbar is overlay-only
scrollbar-gutter: stable both-edges does not reserve layout space for overlay scrollbars, which are common on touch browsers. The unconditional override here therefore changes the existing p-3 inset from 12px to 2px on those devices, leaving chat content almost flush with the screen edge. Keep p-3 as the fallback; only subtract padding when a nonzero classic gutter has actually been detected.
Suggested fix:
@media (hover: none) and (pointer: coarse) {
.chat-scroll-y {
scrollbar-gutter: stable both-edges;
}
/* Do not override .chat-scroll-content padding without a measured gutter. */
}There was a problem hiding this comment.
Fixed in 9dd77d7. The chat viewport now measures the gutter actually reserved by the browser and subtracts only that amount. Overlay-scrollbar devices report a zero physical gutter and therefore keep the original 12px content padding.
There was a problem hiding this comment.
Findings
- None.
Summary
Review mode: follow-up after new commits
No issues found in the latest full diff. The new commits address the prior document-locking and overlay-scrollbar findings. Residual risk: scrollbar-gutter and mobile viewport behavior remain browser-engine dependent, and this PR adds no automated browser coverage for those cases.
Testing
Not run (review automation; PR code was not executed). Suggested coverage: Playwright checks for chat-only document containment plus effective 12px side insets with both classic and overlay scrollbar configurations.
HAPI Bot
Summary
Problem
Some chat sessions could intermittently gain two vertical scrollbars, especially after an image attachment changed size during rendering. The outer document scrollbar could retain a stale scroll range and expose a large blank area below the app until the page was refreshed.
On mobile, the remaining chat scrollbar also consumed width on the right side of the scroll viewport. Centered chat content was therefore shifted left and had visibly asymmetric side spacing.
Changes
html,body, and#rootoverflow containment to pages containing the chat viewport so temporary chat child measurements cannot expand the document scroll range.app-scroll-ysurface(hover: none) and (pointer: coarse):scrollbar-gutter: stable both-edgesp-3content spacing on desktop pointer devicesTesting
bun typecheckbun run test:web— 193 files, 1705 tests passedAI disclosure
Code and PR text were prepared with OpenAI GPT-5.6-Sol and manually tested/reviewed.