E5.07.3infinite scroll restorationdesignresearch

Restoring list position on return is mandatory

Aliases: return to list offset · scroll anchor

What it is

After opening a detail from an infinite list and coming back, people expect to still sit on the same row, not to be thrown to the top to scroll the same stretch again. Scroll restoration on this kind of list is not a nicety: there is no page number to use as a coordinate, so once place is lost, the cost of finding it again grows with how far they had already gone. It is “am I still here after a round trip”, not whether an ending exists, and not whether the footer is reachable.

Why it happens

An infinite list’s coordinate system is fragile. Items have no stable page number, only an offset at the time, an anchor id, and a loaded window. Opening a detail often unmounts or virtualises the list; if return rebuilds only the first page, the anchor is not in the DOM and the browser’s default restoration cannot match. What people see is the familiar first screen, which they read as being sent back to the start, so they abandon further scanning or angrily re-enact the earlier scroll.

Failure also has a time dimension. If the list inserted new items while they were gone (a feed refreshing at the top), restoring by pixels lands on the wrong object; restoring by object id is what “still that row” means. If the loaded window was dropped, even a remembered id requires refetching everything from the top to that id, and the delay looks like restoration never happened. The hard requirement is therefore three layers: still that object, still its surrounding context, and visible immediately on return — not a flash of page one then a jump.

Studying it

Use a leave-and-return task: open an item after more than two screens of scrolling, come back, and measure whether the anchor is in the viewport, offset error, and whether the top appears before a jump. Independent variables: restore strategy (pixels / object id / none) and whether new items were inserted while away. Dependent variables: a judgement of “still that row”, distance re-scrolled, spoken frustration or abandonment.

Score cold starts after process death separately. In-session failure is a defect; a cold start should at least restore to the object id, with the surrounding window allowed to fill in asynchronously.

Where it stops holding

After a filter, sort, or login change, the old anchor may not exist in the new results; restoring to a vanished item becomes an error page. Then land at the top of the list and say the content updated, rather than sticking on a blank. If the user deleted the item in the detail, it should be gone on return; land on a neighbour. Very long virtualised lists on low-end devices cannot rebuild the window in one frame; a skeleton that then settles on the anchor is allowed, but people must not be able to interact with the top before being yanked away. Pull-to-refresh is the user throwing away current place on purpose.

Applying it

  • On leaving the list, record object id, a few neighbours, and relative position in the viewport. On return, ensure that id is already inside the loaded window, then scroll to it — do not render page 1 first.
  • If new items were inserted at the top while away, restore by object, not by pixels. Hint that there is new content above rather than dragging people to the top.
  • If the anchor is gone, land on a neighbour or the top and say why; avoid a blank.
  • How to check: scroll at least two screens, open a detail, return. The anchor must be in the viewport immediately, with no flash of the top. Insert new items while away; return should still be the same row. Every recording in which someone scrolls down from the top again is a restoration failure.

Related

  • Within the group: E5.07.1 Infinite scroll erases location and a sense of ending · E5.07.2 Footer content becomes unreachable
  • Adjacent: E5.02 Bottom Tab Bars · E5.08 Load More Buttons
  • Search terms: scroll restoration · infinite scroll · scroll anchor

Cards in the same group

Quick Actions

Share

Share this page

ios_share

https://hci.top/en/handbook/E5.07.3