scroll-padding

scroll-padding insets the optimal viewing region of a scroll container. It changes where targets are aligned; it does not add ordinary padding or move all content away from the edge.

Leave a container-wide viewing inset

Before clicking, the first content begins at the container edge. After scrolling to the target, 24px of viewing space remains above it.

scroll-padding 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;
}
.viewport {
  scroll-padding: 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.

Reserve viewing space below a sticky toolbar

The inset is on the container, so it applies to targets inside it. The actual toolbar is still positioned by CSS; scroll-padding does not create it.

scroll-padding 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;
}
.viewport {
  scroll-padding-block-start: 48px;
}
.toolbar {
  position: sticky;
  top: 0;
  height: 40px;
  background: #172554;
  color: white;
}

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.

Values and defaults

The shorthand sets top/right/bottom/left offsets using one-to-four values. The initial longhands are auto, and the property is not inherited. Auto normally produces a zero inset but allows browser choice. Explicit offsets use nonnegative lengths or percentages; percentages resolve against the corresponding scrollport dimension. Logical longhands follow the container’s axes.

Common mistakes

This is not a substitute for padding. It applies to scroll containers even when scroll snapping is disabled. Put it on the scrolling box; put scroll-margin on an individual target. Combining both adds their alignment effects, which can leave more room than intended. The scrolling range still limits the final position.

Learn scroll-snap-type, padding, and overflow.

Sources and browser support

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