We've all been there: you're halfway through a fascinating long-form article, your thumb is poised to scroll, and suddenly—zip—the text vanishes. An ad loaded at the top of the page, or a late-arriving image finally popped into place, and your reading position was unceremoniously punted three paragraphs down. It's frustrating, it's jarring, and frankly, it's a bit of a UX disaster.

Right, let's talk about how we finally fix this for good. With the release of Safari 27, scroll anchoring has officially hit "Baseline Newly available" status. This means all major engines—WebKit, Blink, and Gecko—now support a mechanism to keep users locked onto their content even when the DOM is shifting above their heads.

What Shipped and Why It Matters

Safari 27 introduced scroll anchoring as a default behaviour. As WebKit noted in their announcement, this prevents those annoying visual jumps when content is inserted or removed above the viewport. The browser essentially tracks where you are and adjusts the scroll position in the background to compensate for layout changes.

The W3C CSS Scroll Anchoring specification describes this as a way to "mitigate this jarring user experience." It's a win for accessibility and general usability, but as UX engineers, we need to understand the control surface: the overflow-anchor property.

  • auto: The default. The browser tries to find an 'anchor node' to keep in view.
  • none: Opts an element (and its children) out of being used as an anchor.

The Implementation Pattern

In my experience, the secret to a great interface isn't just letting the browser handle everything—it's knowing when to take the wheel. While anchoring is great for asynchronous images loading in, it can be a nuisance for live feeds or chat apps where you want the scroll to behave a specific way.

Here's how I approach the CSS. We keep the feed stable by default, but we might opt out specific 'live regions' if we're managing those updates manually via JavaScript.

/* Default: let supported browsers preserve the reading position. */
.feed {
  overflow-anchor: auto;
}

/* Opt out for a region whose mutations are intentionally managed. */
.feed__live-region {
  overflow-anchor: none;
}

Balancing Intentional Navigation

When a user makes a choice—like clicking a 'Jump to latest' button—user intent must trump the browser's anchoring logic. If they're reading history, keep them anchored. If they're at the bottom, keep them at the bottom. Here's a pattern I've found works brilliantly for prepending messages:

const feed = document.querySelector(".feed");

function prependMessages(messages) {
  // Are they already at the bottom? 
  const wasNearBottom = feed.scrollHeight - feed.scrollTop - feed.clientHeight < 80;

  const oldHeight = feed.scrollHeight;
  feed.prepend(...messages);

  if (wasNearBottom) {
    feed.scrollTop = feed.scrollHeight;
  } else {
    // Let anchoring work, or manually adjust if needed
    feed.scrollTop += feed.scrollHeight - oldHeight;
  }
}

And when you're moving focus programmatically, make sure the browser knows you mean it. I like to use scrollIntoView combined with a focus call that doesn't fight the scroll position.

function revealAndFocus(target) {
  target.scrollIntoView({ block: "center", behavior: "smooth" });
  target.tabIndex = -1;
  // preventScroll: true stops the focus call from jumping elsewhere
  target.focus({ preventScroll: true });
}

Common Gotchas to Watch For

I've seen a few developers try to 'enable' anchoring by setting overflow-anchor: auto everywhere. You don't need to do that! It's already on. The real trick is knowing when to turn it off. Also, remember that anchoring isn't a silver bullet for performance—it's a safety net for layout shifts.

  • Don't disable anchoring document-wide; you'll bring back the jumps for images and ads.
  • Still reserve space for images using aspect-ratio; anchoring reduces movement but doesn't solve the CLS (Cumulative Layout Shift) score entirely.
  • Nested scrollers can be tricky—always test which container is actually doing the scrolling.
  • Avoid fighting the browser every frame. If you're manually setting scrollTop inside a RequestAnimationFrame while the browser is trying to anchor, you'll get nasty jitters.
• • •

I cover this and the other twenty-seven CSS shifts of 2026 in Modern CSS 2026 on Amazon, my catch-up book for people who learned CSS five years ago.

Wrapping Up

  • Scroll anchoring is now a cross-browser standard as of Safari 27, enabled by default to stop layout jumps.
  • Use overflow-anchor: none sparingly on specific regions where you need manual control over the scroll position.
  • Always let user intent (like clicking a link or button) override the browser's attempt to stay anchored.

I'd encourage you to open your current project in the Safari 27 beta and see how your feeds behave. You might find you can delete a lot of hacky resize-observer code!

If you want to go deeper and learn how to build real, production-ready CSS design systems step by step, check out my full course here: CSS Design Systems Course

For more updates on CSS Architecture and UX Engineering, catch me on Twitter or connect with me on LinkedIn.