scroll-margin

scroll-margin adds an outset to a target’s scroll-snap area. It also affects target positioning for operations such as scrollIntoView. It does not reserve normal layout space around the element.

Leave room above a scroll target

Click the button. The target aligns 24px below the scrollport’s top instead of flush against it; that space is a scroll-target adjustment, not a layout margin.

scroll-margin comparisonLink

HTML and CSS

HTML

<button
  type="button"
  onclick="document.getElementById('target').scrollIntoView({block: 'start'})"
>
  Scroll to target
</button>
<div
  class="viewport"
  tabindex="0"
  role="region"
  aria-label="Scrollable practice area"
>
  <div class="spacer">Scroll area begins here.</div>
  <p class="target" id="target">Target paragraph</p>
  <div class="spacer">Space after the target.</div>
</div>

CSS

.viewport {
  height: 150px;
  overflow: auto;
  border: 2px solid #94a3b8;
}
.spacer {
  height: 180px;
  background: #eff6ff;
}
.target {
  padding: 0.75rem;
  background: #bfdbfe;
  margin: 0;
}
button {
  padding: 0.75rem;
  font: inherit;
  margin-bottom: 0.5rem;
}
.target {
  scroll-margin: 24px 0 0;
}

Edit HTML or CSS to update the preview as you type. Copy code snippet copies the selected tab. Preview spacing and font defaults are not included.

Account for a sticky toolbar

The target’s block-start scroll margin accounts for the 40px toolbar. The target stays in its ordinary flow position until the scroll operation occurs.

scroll-margin practical exampleLink

HTML and CSS

HTML

<button
  type="button"
  onclick="document.getElementById('target').scrollIntoView({block: 'start'})"
>
  Scroll to target
</button>
<div
  class="viewport"
  tabindex="0"
  role="region"
  aria-label="Scrollable practice area"
>
  <div class="toolbar">Sticky toolbar</div>
  <div class="spacer">Scroll area begins here.</div>
  <p class="target" id="target">Target paragraph</p>
  <div class="spacer">Space after the target.</div>
</div>

CSS

.viewport {
  height: 150px;
  overflow: auto;
  border: 2px solid #94a3b8;
}
.spacer {
  height: 180px;
  background: #eff6ff;
}
.target {
  padding: 0.75rem;
  background: #bfdbfe;
  margin: 0;
}
button {
  padding: 0.75rem;
  font: inherit;
  margin-bottom: 0.5rem;
}
.toolbar {
  position: sticky;
  top: 0;
  height: 40px;
  background: #172554;
  color: white;
}
.target {
  scroll-margin-block-start: 48px;
}

Edit HTML or CSS to update the preview as you type. Copy code snippet copies the selected tab. Preview spacing and font defaults are not included.

Syntax and defaults

The shorthand sets physical top/right/bottom/left scroll margins with the same one-to-four expansion as margin. Initial longhands are zero, and they are not inherited. Values are lengths; percentages are invalid. Use logical longhands such as scroll-margin-block-start when the target’s writing mode should determine the edge.

Common mistakes

Put scroll-margin on the target, not the container. Unlike ordinary margin, it does not move surrounding elements or enlarge the normal layout box. Alignment is constrained by available scrolling range, so a target near the end may not reach the requested position. A later shorthand resets omitted sides.

Learn scroll-padding for a container-wide viewing inset, scroll-snap-align, and position.

Sources and browser support

MDN: scroll-margin describes the syntax and links to the specification and compatibility data. Check individual values in that table when supporting older browsers.