Skip to content

Commit eb7d041

Browse files
gary149claude
andauthored
Fix chat auto-scroll on touch devices (iOS) (#2390)
* fix(chat): use instant scroll on touch to land the spacer pin on iOS On send, the chat inflates a tall bottom spacer and scrolls to the bottom so the just-sent user message pins near the top (ChatGPT-style). That scroll was issued with behavior: "smooth". On iOS, WebKit suppresses/defers programmatic scrolls during touch/momentum, and the deferred smooth animation only plays out once the gesture and stream settle — i.e. the view visibly scrolls up right as the reply finishes. Use an instant scroll on touch devices (pointer: coarse) so the spacer that was added is snapped into view immediately on send, with no late animation. Desktop keeps its smooth pin. The mobile pin behaviour itself is preserved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DZA6zBsc61PSuo8kg4yRB7 * fix(chat): use any-pointer:coarse so hybrid touch devices snap on send pointer:coarse only reflects the primary pointer, so a hybrid device (touch laptop, iPad with a trackpad) reports fine and keeps the smooth scroll that WebKit defers when touch-scrolling. Switch to any-pointer:coarse so any touch-capable device snaps to the bottom immediately on send. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DZA6zBsc61PSuo8kg4yRB7 --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent f98711a commit eb7d041

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

src/lib/components/chat/ChatWindow.svelte

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,13 @@
337337
last?.content === "";
338338
339339
if (userJustSentMessage) {
340-
scrollBehavior = "smooth";
340+
// Touch devices (iOS): a smooth programmatic scroll is suppressed during
341+
// touch/momentum and only animates once the gesture/stream settle — i.e. the
342+
// view visibly scrolls up right as the reply finishes. An instant scroll snaps
343+
// to the bottom (revealing the freshly inflated spacer) immediately on send.
344+
// `any-pointer: coarse` so hybrid devices (touch laptop, iPad + trackpad) that
345+
// can still touch-scroll snap instantly even when the primary pointer is fine.
346+
scrollBehavior = window.matchMedia("(any-pointer: coarse)").matches ? "instant" : "smooth";
341347
forceReattach++;
342348
// Only activate dynamic spacer after the first exchange
343349
// (first user+assistant pair scrolls normally)

0 commit comments

Comments
 (0)