CSS scroll-padding

Explore how scroll-padding moves a scroll container’s optimal viewing region inward without changing layout. Apply one shared value or adjust every side independently.

Ask AI

CSS scroll-padding

Response generated with openai/gpt-5.4-nano. AI can make mistakes. Always review the result.
What to look for

Align card 05 and change the value. At start it moves away from the top and left; at end, from the bottom and right.

Orange area: inner region where the card aligns

Target 1

Scroll to place this card inside the optimal region.

Target 2

Scroll to place this card inside the optimal region.

Target 3

Scroll to place this card inside the optimal region.

Target 4

Scroll to place this card inside the optimal region.

Test target

Target 5

Scroll to place this card inside the optimal region.

Target 6

Scroll to place this card inside the optimal region.

Target 7

Scroll to place this card inside the optimal region.

Target 8

Scroll to place this card inside the optimal region.

Target 9

Scroll to place this card inside the optimal region.

HTML
<div class="scrollport" aria-label="Interactive scroll-padding area" tabindex="0">
  <article
    class="snap-target"
    style="--target-color: #ffb38a"
    tabindex="0"
  >
    <h2>Target 1</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="snap-target"
    style="--target-color: #72d6c9"
    tabindex="0"
  >
    <h2>Target 2</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="snap-target"
    style="--target-color: #b6a8ff"
    tabindex="0"
  >
    <h2>Target 3</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="snap-target"
    style="--target-color: #ffd166"
    tabindex="0"
  >
    <h2>Target 4</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="snap-target"
    style="--target-color: #f7a6c4"
    tabindex="0"
  >
    <h2>Target 5</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="snap-target"
    style="--target-color: #8ecae6"
    tabindex="0"
  >
    <h2>Target 6</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="snap-target"
    style="--target-color: #a7df9b"
    tabindex="0"
  >
    <h2>Target 7</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="snap-target"
    style="--target-color: #f4a261"
    tabindex="0"
  >
    <h2>Target 8</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="snap-target"
    style="--target-color: #90caf9"
    tabindex="0"
  >
    <h2>Target 9</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
</div>
Tailwind CSS
Some classes with arbitrary values can be replaced by native classes, depending on the value and your Tailwind CSS configuration.
<div class="grid grid-cols-[repeat(3,minmax(16rem,72%))] auto-rows-[72%] gap-6 inline-[min(100%,36rem)] block-96 m-0 p-6 overflow-auto overscroll-contain snap-both snap-mandatory scroll-p-[24px]" aria-label="Interactive scroll-padding area" tabindex="0">
  <article
    class="box-border grid content-end gap-2 p-6 border rounded-2xl text-[#172033] snap-start *:m-0 [&_h2]:text-[clamp(1.5rem,1rem_+_2vw,2.5rem)] focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#ffb38a_72%,#172033)] bg-[#ffb38a]"
    tabindex="0"
  >
    <h2>Target 1</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-6 border rounded-2xl text-[#172033] snap-start *:m-0 [&_h2]:text-[clamp(1.5rem,1rem_+_2vw,2.5rem)] focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#72d6c9_72%,#172033)] bg-[#72d6c9]"
    tabindex="0"
  >
    <h2>Target 2</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-6 border rounded-2xl text-[#172033] snap-start *:m-0 [&_h2]:text-[clamp(1.5rem,1rem_+_2vw,2.5rem)] focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#b6a8ff_72%,#172033)] bg-[#b6a8ff]"
    tabindex="0"
  >
    <h2>Target 3</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-6 border rounded-2xl text-[#172033] snap-start *:m-0 [&_h2]:text-[clamp(1.5rem,1rem_+_2vw,2.5rem)] focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#ffd166_72%,#172033)] bg-[#ffd166]"
    tabindex="0"
  >
    <h2>Target 4</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-6 border rounded-2xl text-[#172033] snap-start *:m-0 [&_h2]:text-[clamp(1.5rem,1rem_+_2vw,2.5rem)] focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#f7a6c4_72%,#172033)] bg-[#f7a6c4]"
    tabindex="0"
  >
    <h2>Target 5</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-6 border rounded-2xl text-[#172033] snap-start *:m-0 [&_h2]:text-[clamp(1.5rem,1rem_+_2vw,2.5rem)] focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#8ecae6_72%,#172033)] bg-[#8ecae6]"
    tabindex="0"
  >
    <h2>Target 6</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-6 border rounded-2xl text-[#172033] snap-start *:m-0 [&_h2]:text-[clamp(1.5rem,1rem_+_2vw,2.5rem)] focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#a7df9b_72%,#172033)] bg-[#a7df9b]"
    tabindex="0"
  >
    <h2>Target 7</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-6 border rounded-2xl text-[#172033] snap-start *:m-0 [&_h2]:text-[clamp(1.5rem,1rem_+_2vw,2.5rem)] focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#f4a261_72%,#172033)] bg-[#f4a261]"
    tabindex="0"
  >
    <h2>Target 8</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-6 border rounded-2xl text-[#172033] snap-start *:m-0 [&_h2]:text-[clamp(1.5rem,1rem_+_2vw,2.5rem)] focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#90caf9_72%,#172033)] bg-[#90caf9]"
    tabindex="0"
  >
    <h2>Target 9</h2>
    <p>Scroll to place this card inside the optimal region.</p>
  </article>
</div>
CSS
.scrollport {
  display: grid;
  grid-template-columns: repeat(3, minmax(16rem, 72%));
  grid-auto-rows: 72%;
  gap: 1.5rem;
  inline-size: min(100%, 36rem);
  block-size: 24rem;
  margin: 0;
  padding: 1.5rem;
  overflow: auto;
  overscroll-behavior: contain;
  scroll-snap-type: both mandatory;
  scroll-padding: 24px;
}

.snap-target {
  box-sizing: border-box;
  display: grid;
  align-content: end;
  gap: 0.5rem;
  padding: 1.5rem;
  border: 1px solid color-mix(in oklch, var(--target-color) 72%, #172033);
  border-radius: 1rem;
  background: var(--target-color);
  color: #172033;
  scroll-snap-align: start;
}

.snap-target > * {
  margin: 0;
}

.snap-target h2 {
  font-size: clamp(1.5rem, 1rem + 2vw, 2.5rem);
}

.snap-target:focus-visible {
  outline: 4px solid #172033;
  outline-offset: -8px;
}