CSS Portal

CSS overflow-anchor Property

If this site has been useful, we’d love your support! Consider buying us a coffee to keep things going strong!

Description

The overflow-anchor property controls whether an element participates in the browser’s scroll-anchoring behavior — the mechanism browsers use to try to keep the user’s viewport stable when content above or around the current view changes (for example, when images load, ads are inserted, or DOM nodes are prepended). When an element participates as an anchor, the browser can choose it as a reference point and adjust the scroll position to compensate for layout changes so the user doesn’t unexpectedly jump to a different part of the content. This is a layout-level hint rather than a guarantee: the UA uses heuristics to pick anchors and decide when to apply adjustments, so results are best considered as “helpful” rather than strictly deterministic.

Because anchoring applies to scroll containers, it interacts with how and where scrolling happens on the page — in particular the visible box that actually scrolls. That means it is closely related to the behavior of the element’s overflow properties; for example, whether an element creates an overflow context may determine which container’s scroll position is adjusted (overflow). It also respects CSS containment: containment rules that isolate layout or size can prevent anchoring from crossing element boundaries (contain). In short, anchoring decisions are made in the context of the surrounding layout model, not in isolation.

In practice, you use this capability to improve perceived stability for end users or to avoid unwanted automatic adjustments. For instance, for feeds or chat windows where new content is appended or prepended, anchoring can preserve a reader’s place; conversely, on complex, dynamically resized widgets you may prefer to opt an element out of anchoring to prevent the browser from trying to compensate and causing awkward jumps. Consider the interaction with scripted scrolling and smooth scrolling settings when designing UX — automated adjustments can conflict with developer-initiated scrolls or with CSS-driven smooth motions (scroll-behavior) — so test dynamic content changes to make sure the behavior matches user expectations.

When troubleshooting unexpected scroll jumps, reproduce the content changes (for example, loading an image, inserting a node, or toggling visibility) and observe whether the browser is using an anchor inside the scrolling container; adjusting which elements participate can make shifts more predictable. Keep in mind that because anchors are chosen with heuristics and are influenced by layout containment and scroll context, the same page could behave differently under different viewport sizes or content loading sequences, so validate across the conditions your users will encounter.

Definition

Initial value
auto
Applies to
all elements
Inherited
no
Computed value
as specified
Animatable
yes
JavaScript syntax
object.style.overflowAnchor

Syntax

overflow-anchor: auto | none

Values

  • autoThe element becomes a potential anchor when adjusting scroll position.
  • noneThe element won't be selected as a potential anchor.

Example

<div class="example">
<h2>overflow-anchor demo</h2>
<div class="panels">
<div class="panel">
<h3>Anchored (overflow-anchor: auto)</h3>
<button class="add-btn" data-target="anchored">Insert item above</button>
<div class="content anchored" id="anchored" tabindex="0">
<div class="item">Item 20</div>
<div class="item">Item 19</div>
<div class="item">Item 18</div>
<div class="item">Item 17</div>
<div class="item">Item 16</div>
<div class="item">Item 15</div>
<div class="item">Item 14</div>
<div class="item">Item 13</div>
<div class="item">Item 12</div>
<div class="item">Item 11</div>
<div class="item">Item 10</div>
<div class="item">Item 9</div>
<div class="item">Item 8</div>
<div class="item">Item 7</div>
<div class="item">Item 6</div>
<div class="item">Item 5</div>
<div class="item">Item 4</div>
<div class="item">Item 3</div>
<div class="item">Item 2</div>
<div class="item">Item 1</div>
</div>
</div>

<div class="panel">
<h3>Unanchored (overflow-anchor: none)</h3>
<button class="add-btn" data-target="unanchored">Insert item above</button>
<div class="content unanchored" id="unanchored" tabindex="0">
<div class="item">Item 20</div>
<div class="item">Item 19</div>
<div class="item">Item 18</div>
<div class="item">Item 17</div>
<div class="item">Item 16</div>
<div class="item">Item 15</div>
<div class="item">Item 14</div>
<div class="item">Item 13</div>
<div class="item">Item 12</div>
<div class="item">Item 11</div>
<div class="item">Item 10</div>
<div class="item">Item 9</div>
<div class="item">Item 8</div>
<div class="item">Item 7</div>
<div class="item">Item 6</div>
<div class="item">Item 5</div>
<div class="item">Item 4</div>
<div class="item">Item 3</div>
<div class="item">Item 2</div>
<div class="item">Item 1</div>
</div>
</div>
</div>
</div>

<script>
// Prepend a timestamped item to the chosen scroll container
document.querySelectorAll('.add-btn').forEach(function(btn) {
btn.addEventListener('click', function() {
var targetId = btn.getAttribute('data-target');
var container = document.getElementById(targetId);
var newItem = document.createElement('div');
newItem.className = 'item new';
newItem.textContent = 'New item - ' + new Date().toLocaleTimeString();

// Insert at top to simulate content added above the current viewport
container.prepend(newItem);

// Briefly highlight the new item
setTimeout(function() { newItem.classList.remove('new'); }, 800);
});
});
</script>
/* Layout */
.example {
  font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial;
  padding: 18px;
  max-width: 980px;
  margin: 0 auto;
  color: #111;
}

.panels {
  display: flex;
  gap: 18px;
  margin-top: 12px;
}

.panel {
  flex: 1;
  min-width: 280px;
}

h2 {
  margin: 0 0 8px 0;
  font-size: 18px;
}

h3 {
  margin: 0 0 8px 0;
  font-size: 14px;
}

button.add-btn {
  display: inline-block;
  margin-bottom: 8px;
  padding: 8px 10px;
  font-size: 13px;
  cursor: pointer;
  border: 1px solid #ccc;
  background: #f7f7f7;
  border-radius: 6px;
}

/* Scrollable content */
.content {
  height: 220px;
  overflow-y: auto;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  padding: 8px;
  background: linear-gradient(#fff, #fbfbfc);
}

/* Key property: one side keeps the scroll anchor, the other disables it */
.content.anchored {
  overflow-anchor: auto; /* default; explicitly set for demo */
}

.content.unanchored {
  overflow-anchor: none; /* disabling automatic scroll anchoring */
}

.item {
  padding: 10px 12px;
  margin-bottom: 8px;
  background: #fff;
  border-radius: 6px;
  box-shadow: 0 1px 0 rgba(0,0,0,0.03);
  font-size: 13px;
}

.item.new {
  background: #fff7d9;
  border: 1px solid #ffe58f;
  transition: background 0.6s ease;
}

/* Small responsive tweak */
@media (max-width: 720px) {
  .panels { flex-direction: column; }
}

Browser Support

The following information will show you the current browser support for the CSS overflow-anchor property. Hover over a browser icon to see the version that first introduced support for this CSS property.

This property is supported in some modern browsers, but not all.
Desktop
Chrome
Edge
Firefox
Opera
Safari
Tablets & Mobile
Chrome Android
Firefox Android
Opera Android
Safari iOS
Samsung Internet
Android WebView
-

Last updated by CSSPortal on: 1st January 2026

If this site has been useful, we’d love your support! Consider buying us a coffee to keep things going strong!