react-scroll-to-bottom
react-scroll-to-bottom copied to clipboard
Loosing stickiness on simultaneous inserts&removals
Hello.
I have a list of messages with frequent additions. Messages have random height (they are text with word wrap). This list also have a limit of messages, when there is more messages than a limit — old messages should be hidden.
In such circumstances after some time scrolling to bottom stops.
I prepared demo, that illustrates this behavior — https://github.com/Rulexec/react-scroll-to-bottom/tree/limited-scroll-demo

Wow, thanks for the repro in repo. Please keep it there. Will definitely look at it.
I'm having the same issue. I think the problem is related to having a limit of messages. If I keep all the messages in the stream, scrolling works fine, even if sometimes there are multiple additions in very quick sequence. But if at the same time that I add new lines I remove old ones, scrolling breaks.
I am seeing this one by removing the first paragraph, and adding a new one at the end.
Will fix it in next schedule.
I am having the same issue, any news on when it will be resolved?
I just added an automated test harness that will help reproducing this bug. I saw it too.
After I completed hygiene works on this repository (bump deps, add static code analysis, etc), I will work on this. This is a high priority bug.
Done some investigations:
- It only repro if elements inserted and removed are of same size
- This also includes moving the first element to the end of the list (insert/remove of same size)
Root cause:
- Interference with Chromium "artificial scroll" feature
- Artificial scrolling, means:
- At middle/bottom of the list, when an element at top is removed, Chromium will artificially scroll to keep the viewport unmoved
- It means,
scrollTopwill change, andscrollevent will be fired.scrollTopwill be set to a number to keep the viewport unmoved, i.e.scrollTop -= elementRemoved.clientHeight
- It means,
- This reduce jumpy UX, end-user won't notice an element was removed because the viewport won't move, only the scrollbar handle will change its position
- At middle/bottom of the list, when an element at top is removed, Chromium will artificially scroll to keep the viewport unmoved
- We have logic to differentiate whether the
scrollevent is done by the end-user or by Chromium- If it is by Chromium, we will keep it sticky
- If it is done by end-user, we will unstick
- E.g. mouse wheel, two-finger on precision touchpad, Xbox right joystick, two-finger on Synaptics driver (non-precision)
- The insertion/removal caused a false positive in this check: we think the scroll is done by end-user, instead, it was done by Chromium
- The check is: on
scrollevent, if the content height and scrollable height is kept unchanged, it is done by Chromium
- The check is: on
- Due to false positive, we unstick the view
To fix this issue, we will need to rewrite the logic.
@compulim I fought with a similar problem in my library. As I remember it is related to scroll anchoring.
Try to add:
overflow-anchor: none
To your main scrolling div. I have tested it a bit with the @Rulexec repro and it seems to work.
Resources:
- https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-anchor/Guide_to_scroll_anchoring
- https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-anchor