From 61f7f86f18bed1a9279b7492acb5397928a0d4ae Mon Sep 17 00:00:00 2001 From: Damian Pieczynski Date: Mon, 14 Sep 2026 08:17:11 +0200 Subject: [PATCH] docs(chat): recommend overscroll-behavior: none on the scroll element Safari discards a scrollTop write made while an inner scroller is rubber-banding past its top edge and animates back to 0. In a chat that loads history when the user reaches the top, a prepend landing during the bounce loses its anchor write and the reader ends up a whole prepend away from their row (#1287). Suppressing the bounce with `overscroll-behavior: none` closes that window; verified in Safari 18.4. Adds it to the chat guide's production checklist next to `overflow-anchor: none`, which the react chat example already set but the guide did not mention, and applies it to the example's scroller. Refs #1287 Co-Authored-By: Claude Fable 5.1 --- docs/chat.md | 2 ++ examples/react/chat/src/index.css | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/docs/chat.md b/docs/chat.md index 7eb6bdf6f..c772a7b12 100644 --- a/docs/chat.md +++ b/docs/chat.md @@ -129,6 +129,8 @@ Use a normal scroll container and normal item order. You do not need `flex-direc - Use stable message ids with `getItemKey`. - Give the scroll element a fixed height and `overflow: auto`. +- Set `overflow-anchor: none` on the scroll element so the browser's own scroll anchoring does not fight the virtualizer's prepend compensation. +- Set `overscroll-behavior: none` on the scroll element. Safari discards a `scrollTop` write made while the scroller is rubber-banding past its top edge, so history that lands mid-bounce would lose its anchor; suppressing the bounce closes that window. - Call `measureElement` for dynamic message heights. - Use `anchorTo: 'end'` for prepend stability and streaming bottom growth. - Use `followOnAppend` when new output should follow only from the latest position. diff --git a/examples/react/chat/src/index.css b/examples/react/chat/src/index.css index e8e379d47..ce1de49dd 100644 --- a/examples/react/chat/src/index.css +++ b/examples/react/chat/src/index.css @@ -71,6 +71,10 @@ button:hover { min-height: 0; overflow: auto; overflow-anchor: none; + /* Suppress the elastic bounce at the edges (Safari): a scrollTop write + made mid-bounce is discarded by WebKit, so a prepend landing during the + bounce would lose its anchor (#1287). */ + overscroll-behavior: none; width: 100%; }