C1.11.3Scroll anchoringdesignresearch

Scroll-position jumps and anchoring under asynchronous loading

Aliases: scroll anchoring · layout shift · asynchronous loading

What it is

Scroll anchoring tries to keep content people are viewing in the same visual position when images, ads, collapsed regions, or asynchronous data change page height. Without it, inserted content displaces the reading location, causing sudden jumps, misclicks, and re-search.

Why it happens

The system picks a stable element within the viewport as an anchor and compensates the scroll offset whenever layout above it changes, so the anchor stays at the same screen position. Anchor choice, reserved content size, animation, and active user scrolling all affect the compensation; if it lags behind rendering or the anchor keeps switching, visual jitter still appears.

Anchor selection is the step most prone to failure. Most implementations pick the element nearest the top of the viewport that is itself not changing, as the anchor. If that very element also happens to be changing — say it sits right above an image still loading, and a layout engine folds both into the same reflow — the compensation math uses the wrong reference and produces a jump stranger than having no anchoring at all: content jumps once, then gets "corrected" back, which invites misclicks more readily than a single clean jump. This is why anchoring cannot patch over layout shift by itself; it must pair with a strategy for reserving content size. Anchoring handles "how to compensate after a change happens," reserved sizing handles "reducing change at the source" — neither is sufficient alone.

Studying it

Inject delayed images, recommendation modules, and expanding content into reading, form-filling, and list-browsing tasks. Measure viewport displacement, reorientation time, misclicks, and abandonment. Test active scrolling, paused reading, and bottom-loading separately, since intent changes what "preserving position" should even mean. To locate where the anchor-selection algorithm itself fails, deliberately construct boundary cases where the anchor element is itself changing — ordinary content-injection experiments rarely cover this compound scenario.

Where it stops holding

Anchoring must not prevent people from intentionally jumping to new content — a new-message indicator in chat, an error location after submission, or an explicit anchor-link click. For regions whose height is extremely unstable, reserved space, a skeleton screen, or an explicit "new content available" notice can be more predictable than repeated compensation — especially once content changes frequently enough that the anchor keeps switching, at which point the repeated compensation itself becomes a new source of disruption, and it is better to give up on anchoring in favour of a fixed placeholder.

Applying it

  • Reserve dimensions for images, ads, and asynchronous modules to reduce layout change before relying on anchoring compensation; the two are complementary, not substitutes for each other.
  • Keep the reading region stable; surface new content through a notice and let people choose it rather than forcing a jump.
  • How to check: test viewport displacement on slow networks, delayed resources, and content expansion, logging whether people need to re-search for their reading position; specifically test cases where the anchor element itself changes, looking for a secondary "jump then correct" jitter.

Related

  • Same group: C1.11.1 Discrete step scrolling and pixel-level smooth scrolling · C1.11.2 Inertial scrolling friction and stopping expectations · C1.11.4 Scroll hijacking breaks expectations of user control
  • Nearby: I1 State, time, and response · D1 Output and feedback channels
  • Search terms: scroll anchoring · layout shift · anchor node selection

Cards in the same group

Quick Actions

Share

Share this page

ios_share

https://hci.top/en/handbook/C1.11.3