scroll-padding-bottom

Sets the bottom padding of a scroll container to adjust scroll snap positions. Prevents a fixed bottom bar from obscuring content.

Class List

Pattern: spb{value}{unit}

ClassCSSDescription
spb0scroll-padding-bottom: 0No scroll padding
spb8pxscroll-padding-bottom: 8px8px padding
spb16pxscroll-padding-bottom: 16px16px padding
spb2remscroll-padding-bottom: 2rem20px padding
spb4remscroll-padding-bottom: 4rem40px padding
spb6remscroll-padding-bottom: 6rem60px padding

Live Demo

Both boxes have a fake 60px tall bottom bar covering them. Use the buttons above to scroll to a section. On the left the bottom of the section disappears behind the bar; on the right it stops above the bar.

Default — no scroll padding

Section 1

When the button aligns this section to the bottom, watch whether its lower edge ends up behind the bottom bar.

Section 2

When the button aligns this section to the bottom, watch whether its lower edge ends up behind the bottom bar.

Section 3

When the button aligns this section to the bottom, watch whether its lower edge ends up behind the bottom bar.

Section 4

When the button aligns this section to the bottom, watch whether its lower edge ends up behind the bottom bar.

Fixed bottom bar (60px)

The bottom edge of the section sits flush against the container floor and hides behind the bar.

Scroll padding 60px — spb6rem

Section 1

When the button aligns this section to the bottom, watch whether its lower edge ends up behind the bottom bar.

Section 2

When the button aligns this section to the bottom, watch whether its lower edge ends up behind the bottom bar.

Section 3

When the button aligns this section to the bottom, watch whether its lower edge ends up behind the bottom bar.

Section 4

When the button aligns this section to the bottom, watch whether its lower edge ends up behind the bottom bar.

Fixed bottom bar (60px)

Scrolling stops 60px above the container floor, so nothing is hidden by the bar.

Per-class Detail

spb0scroll-padding-bottom: 0

Resets scroll padding to zero, so a scroll target is aligned exactly with the physical bottom of the container.

When to use

Use it when a shared layout sets scroll padding but a particular screen has no bottom bar, and that container should behave normally.

<!-- Reset an inherited scroll padding back to zero -->
<div class="spb0 oya h100vh">
  <section id="s1">Section 1</section>
</div>

spb16pxscroll-padding-bottom: 16px

Leaves 16px of slack so a scroll target is not flush with the bottom edge. Useful for visual breathing room even when nothing covers the container.

When to use

Use it in scroll-snap lists so cards do not look clipped against the container edge.

<!-- Breathing room so a snapped card is not flush with the edge -->
<div class="spb16px oya h60rem sstym">
  <article class="ssae minh20rem bg18181B br8px mb16px">Card 1</article>
  <article class="ssae minh20rem bg18181B br8px mb16px">Card 2</article>
</div>

spb6remscroll-padding-bottom: 6rem

Uses a line 60px above the floor as the alignment edge for scrolling. Pairs with a 60px tall fixed bottom bar.

When to use

Use it to reserve exactly the height of a fixed element layered over the scroll area: a bottom navigation bar, a tab bar, a message composer. Keep the value equal to that element's real height.

<!-- Scroll container sitting under a 60px tall fixed bar -->
<div class="spb6rem oya h100vh">
  <section id="s1">Section 1</section>
  <section id="s2">Section 2</section>
</div>
<footer class="pf b0 l0 w100p h6rem bg18181B">Bottom navigation</footer>

Usage Examples

The basic form for compensating a fixed bottom bar and a mobile tab bar.

<!-- Page with fixed bottom bar -->
<div class="spb6rem oya h100vh">
  <section id="s1">Section 1</section>
  <section id="s2">Section 2</section>
</div>
<footer class="pf b0 l0 w100p h6rem bg18181B">
  Bottom navigation
</footer>

<!-- Mobile bottom tab bar compensation -->
<main class="spb8rem oya">
  Content is not obscured by the bottom tab bar.
</main>

A chat thread with the composer pinned to the bottom. Jumping to a message never leaves it behind the composer.

<!-- Chat thread with a message composer pinned to the bottom -->
<div class="pr h100vh df fdc bg0F0F17">

  <!-- The composer is 80px tall, so the thread reserves 8rem at the bottom -->
  <div class="spb8rem oya fg1 p2rem">
    <article id="msg-101" class="mb16px p16px bg18181B br8px fs14px cA1A1AA">
      Earlier message
    </article>
    <article id="msg-102" class="mb16px p16px bg18181B br8px fs14px cA1A1AA">
      Latest message
    </article>
  </div>

  <div class="pa b0 l0 w100p h8rem bt1pxsolid27272A bg0F0F17 df aic gap8px p16px">
    <input type="text" class="fg1 py8px px12px br8px b1pxsolid27272A" />
    <button class="py8px px16px bg6366F1 cFFFFFF br8px bn cp">Send</button>
  </div>
</div>

<!-- Jumping to a message keeps it clear of the composer -->
<script>
  document.getElementById('msg-102')
    .scrollIntoView({ block: 'end', behavior: 'smooth' });
</script>

Tips & Notes

It belongs on the scroll container

scroll-padding-bottom goes on the element that scrolls. By contrast scroll-margin-bottom goes on the target element. When nothing seems to happen, the two have usually been swapped.

For page-level scrolling, put it on the root

If the document itself scrolls rather than a separate box, the scroll container is the root element. Apply it to the html element; on an inner div it does nothing.

Which scrolls it affects

It only applies to scrolls the browser positions for you: scrollIntoView, anchor navigation, keyboard focus moves, and scroll snapping. Manual wheel scrolling is unaffected.

You only feel it on bottom alignment

If scrollIntoView aligns to the top, bottom padding never shows. For bottom-bar compensation, scroll with bottom alignment or pair it with end alignment in scroll snapping.