CSS overflow-anchor: Scroll Anchoring

Keep the chat log from jumping

Loading older messages used to mean saving scrollHeight, prepending the nodes, then adding the difference back to scrollTop. overflow-anchor lets the browser hold the words you were reading in place.

Old way8 lines
function prependMessage(log, node) {  const prev = log.scrollHeight;  log.prepend(node);  log.scrollTop += log.scrollHeight - prev;}
4 lines
.log   {  overflow-y: auto;  overflow-anchor: auto;}/* browser holds the visible message when older ones prepend */
Newly availableSince 202680% global usage

Since 2026 this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

Works in all modern browsers. May need a fallback for older browsers.

56+
66+
27+
79+

Baseline Newly available since September 2026, when Safari 27 and iOS Safari 27 shipped. Chrome 56, Firefox 66, and Edge 79 already had it. Older Safari still jumps when messages are prepended, so keep the scrollHeight delta behind @supports not (overflow-anchor: auto) if those versions matter.

load older messages. The right log stays on the same line
overflow-anchor: none
Earlier line
The one before
You are reading this.
Reply after it.
The log keeps going.
overflow-anchor: auto
Earlier line
The one before
You are reading this.
Reply after it.
The log keeps going.
Left log jumps to the new line. Right log stays on the line you were reading.

Same pixels stay put

Content inserted above the anchor changes scrollTop in the same layout pass. The line you were reading does not move.

On by default

auto is the initial value. The usual bug is a stylesheet that sets none, or a list of absolutely positioned rows the browser cannot anchor.

Not a stick-to-bottom

Anchoring holds a message that is already on screen. A bubble growing at the end of the log still needs scrollTop = scrollHeight while the reader is following it.

Lines Saved
8 → 4
No scrollHeight delta
Old Approach
scrollTop += delta
Measure, prepend, write scrollTop
Modern Approach
overflow-anchor: auto
Browser adjusts scrollTop

How it works

Scroll anchoring picks an element in the visible area and, when layout above that element changes, moves scrollTop by the same amount. Loading older chat messages, an image finishing above the fold, or a tool row opening higher up the thread all used to shove the viewport. The old compensation stored scrollHeight before the insert and added the difference to scrollTop afterward.

overflow-anchor: auto marks an element as a possible anchor. none takes it out of the running. The initial value is auto, and browsers that support anchoring already do this without a rule. You write auto when a reset set none, or to make the choice obvious. Absolutely positioned rows are not anchor candidates, so a virtualized list that takes every row out of flow turns anchoring off even when the property says auto.

Anchoring does not follow growth of the anchor itself. A streaming reply getting taller, or a new message arriving while the reader is pinned to the end, still needs one scrollTop = scrollHeight write, and only while they are already at the end. Safari 27 and iOS Safari 27 shipped this in September 2026. Chrome has had it since 56, Firefox since 66, and Edge since 79. Global support is about 80% on caniuse. MDN lists it as Baseline Newly available since September 2026.

ESC