scroll-margin-left

Sets the space to keep on the left of an element when it is scrolled into view. It shifts the final resting position for anchor navigation, scrollIntoView calls, and scroll snapping. It has no effect on the element's actual layout.

Class List

Pattern: sml{value}{unit}

ClassCSSDescription
sml0scroll-margin-left: 0No scroll margin
sml8pxscroll-margin-left: 8px8px margin
sml16pxscroll-margin-left: 16px16px margin
sml2remscroll-margin-left: 2rem20px margin
sml4remscroll-margin-left: 4rem40px margin

Live Demo

Each button resets the container and then scrolls the blue card into view aligned to the start. Compare how far the card stops from the left edge for each class.

1
2
3
4
5
6
Target
8
9
10
11
12
13
14

With sml0 the card sits flush against the inner left edge; with sml4rem it stops 40px away. The card's own size and position never change.

Class Details

sml0scroll-margin-left: 0

Resets the scroll margin to zero. Use it when a shared component or an ancestor rule already sets an offset and one particular card should sit flush against the edge.

<!-- Reset an inherited offset for one card -->
<div class="sstxm df oxa gap16px">
  <div class="ssas sml2rem fs0 w28rem">Card 1</div>
  <div class="ssas sml0 fs0 w28rem">Flush against the edge</div>
</div>

sml8pxscroll-margin-left: 8px

8px. The smallest offset that keeps borders and focus rings from being clipped. Suits dense horizontal rows of chips and tags.

<!-- Chip row: just enough to clear the hairline border -->
<div class="sstxm df oxa gap8px">
  <button class="ssas sml8px fs0 py8px px16px">All</button>
  <button class="ssas sml8px fs0 py8px px16px">Design</button>
</div>

sml16pxscroll-margin-left: 16px

16px. Matches a carousel whose cards are 16px apart, so the leading card gets the same breathing room as the gaps between cards.

<!-- Card gutter that matches the 16px gap between cards -->
<div class="sstxm df oxa gap16px">
  <article class="ssas sml16px fs0 w28rem">Card 1</article>
  <article class="ssas sml16px fs0 w28rem">Card 2</article>
</div>

sml2remscroll-margin-left: 2rem

20px. In a layout with 20px horizontal container padding, this lines the snapped card up with the heading and body text above it.

<!-- Match the container padding so snapped cards line up with the header -->
<section class="px2rem">
  <h2>Featured</h2>
  <div class="sstxm df oxa gap16px">
    <article class="ssas sml2rem fs0 w28rem">Card 1</article>
    <article class="ssas sml2rem fs0 w28rem">Card 2</article>
  </div>
</section>

sml4remscroll-margin-left: 4rem

40px. Use it when a pinned rail, icon bar, or indicator sits at the left of the scroll area and must stay uncovered.

<!-- Clear a 40px sticky rail pinned to the left of the scroller -->
<div class="pr">
  <div class="pa t0 l0 w4rem h100p">Rail</div>
  <div class="sstxm df oxa gap16px">
    <article class="ssas sml4rem fs0 w28rem">Card 1</article>
    <article class="ssas sml4rem fs0 w28rem">Card 2</article>
  </div>
</div>

Usage Examples

<!-- Left margin in horizontal scroll snap -->
<div class="sstxm df oxa gap16px">
  <div class="ssas sml2rem fs0 w28rem bg18181B p2rem br8px">Card 1</div>
  <div class="ssas sml2rem fs0 w28rem bg18181B p2rem br8px">Card 2</div>
  <div class="ssas sml2rem fs0 w28rem bg18181B p2rem br8px">Card 3</div>
</div>

Practical example: horizontal step navigation

When the dot navigation jumps to a step, without scroll-margin-left the section lands flush against the container edge and looks cramped.

<!-- Horizontal step navigation: clicking a dot brings the step into view
     with breathing room on its left instead of flush against the edge -->
<nav class="df gap8px mb16px">
  <a href="#step-1" class="w12px h12px br999px bg6366F1"></a>
  <a href="#step-2" class="w12px h12px br999px bg27272A"></a>
  <a href="#step-3" class="w12px h12px br999px bg27272A"></a>
</nav>

<div class="sstxm df oxa gap16px">
  <section id="step-1" class="ssas sml2rem fs0 w30rem p2rem bg18181B br8px">
    <h3>1. Account</h3>
  </section>
  <section id="step-2" class="ssas sml2rem fs0 w30rem p2rem bg18181B br8px">
    <h3>2. Payment</h3>
  </section>
  <section id="step-3" class="ssas sml2rem fs0 w30rem p2rem bg18181B br8px">
    <h3>3. Confirm</h3>
  </section>
</div>

Pitfalls

It only applies when something scrolls the element into view

scroll-margin is consulted for anchor navigation, scrollIntoView, and scroll snapping. Manual scrolling and ordinary layout are completely unaffected.

margin goes on the item, padding goes on the container

scroll-margin-left belongs on individual items, while scroll-padding-left belongs on the scroll container. When every item needs the same offset, one scroll-padding on the container is simpler.

Smooth motion still needs scroll-behavior

scroll-margin only decides the final position. Add scroll-behavior: smooth on the scroll container so the jump is animated instead of instant.