CSS Portal

CSS scroll-margin Property

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

Description

The scroll-margin property controls the offset used by the browser when bringing an element into view via scrolling actions (for example, fragment navigation, programmatic scrolling, or snap alignment). It does not change the element’s layout or its visual spacing in the document flow — instead it adjusts the point within the scrollport at which the element is considered "in view." In practice this means you can shift the final scroll position so the target element stops some distance away from the edge of its scroll container (useful for avoiding fixed headers or creating consistent breathing room around focused items) without altering actual margins in the layout.

This adjustment is applied to the element being scrolled to, not to the scroll container. When used together with CSS Scroll Snap behavior, the effective snap destination results from a combination of the element’s alignment rules and its scroll-margin. For example, the element’s snap alignment setting (scroll-snap-align) determines which edge of the element should line up with the scrollport, while scroll-padding on the container changes the scrollport’s inset; scroll-margin shifts the element’s target position relative to that final alignment. Because these properties act on different parts of the calculation — the element versus the container — they are complementary tools for fine-tuning scroll behavior.

The property operates along the block and inline axes, so you can influence vertical and horizontal scroll positioning independently. It’s also honored by various scrolling mechanisms: fragment links (the :target jump), element.scrollIntoView() and other programmatic scrolls, and snap alignment — and it interacts naturally with smooth scrolling behavior (scroll-behavior) so the adjusted target will be reached smoothly when smooth scrolling is enabled. Keep in mind that because scroll-margin is only used by the scrolling algorithm, it doesn’t affect hit-testing, painting, or how other elements flow around the target.

In practical use, scroll-margin is a reliable way to account for UI chrome (fixed headers, sticky bars) or to create consistent spacing when bringing arbitrary targets into view, without having to restructure the document or add spacer elements. Set it on the elements that will be targeted (anchors, focus targets, snap children) so individual items can define their own scroll offset. Also note that the property only matters when the element participates in a scrollable context; if the element isn’t within a scrollable ancestor for the axis in question, the property has no visible effect.

Definition

Initial value
See individual properties
Applies to
all elements
Inherited
no
Computed value
See individual properties
Animatable
by computed value type
JavaScript syntax
object.style.scrollMargin

Interactive Demo

1
2
3
Scroll »

Syntax

scroll-margin: <length>{1,4} 

Values

  • <length>An outset from the corresponding edge of the scroll container.

Example

<body>
<header class="site-header">
<h1>Scroll-margin Example</h1>
<nav class="nav">
<a href="#section1">Section 1</a>
<a href="#section2">Section 2</a>
<a href="#section3">Section 3</a>
</nav>
</header>

<main class="content">
<section id="section1" class="panel">
<h2>Section 1</h2>
<p>
This section uses a standard scroll-margin-top so when you click the link the
heading clears the fixed header.
</p>
</section>

<section id="section2" class="panel large">
<h2>Section 2 (larger scroll-margin)</h2>
<p>
This section demonstrates a larger scroll-margin-top to create extra space
between the top of the viewport and the element when scrolled into view.
</p>
</section>

<section id="section3" class="panel">
<h2>Section 3</h2>
<p>
Another section using the default scroll-margin-top value.
</p>
</section>
</main>

<footer class="site-footer">
<p>Footer - page end</p>
</footer>
</body>
:root {
  --header-height: 64px;
  --accent: #2b7cff;
}

/* Smooth scrolling for in-page links */
html {
  scroll-behavior: smooth;
}

/* Fixed header to demonstrate overlap behavior */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--header-height);
  background: linear-gradient(90deg, #ffffff, #f3f6ff);
  border-bottom: 1px solid #e6ecff;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  z-index: 10;
}

/* Ensure content is not hidden under the fixed header */
.content {
  padding-top: calc(var(--header-height) + 16px);
  max-width: 800px;
  margin: 0 auto;
}

/* Panels that will be targeted by in-page links */
.panel {
  background: #ffffff;
  border: 1px solid #eef2ff;
  padding: 24px;
  margin: 32px 0;
  border-radius: 8px;
  box-shadow: 0 1px 0 rgba(43, 124, 255, 0.04);

  /* The key property: offset the scrolled position so the element appears
     below the fixed header. Adjust the value as needed. */
  scroll-margin-top: calc(var(--header-height) + 16px);
}

/* One section with a larger scroll-margin for demonstration */
.panel.large {
  scroll-margin-top: calc(var(--header-height) + 48px);
}

/* Basic navigation styling */
.nav a {
  color: var(--accent);
  margin-left: 12px;
  text-decoration: none;
  font-weight: 600;
}

/* Give panels some visible height for scrolling */
.panel {
  min-height: 300px;
}

.panel.large {
  min-height: 600px;
}

.site-footer {
  text-align: center;
  padding: 40px 0;
  color: #666666;
}

Browser Support

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

This property is supported by all modern browsers.
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!