📏 CSS scroll-margin-inline & scroll-margin-block — Complete Tutorial

The CSS scroll-margin-inline andscroll-margin-block properties define extra space added around an element when it becomes the target of scrolling—for example, when using anchor links, scroll snapping, or scrollIntoView().

>>“scroll-margin gives breathing room to the element being scrolled into view — without changing layout.”

Note

✔ Applied on scroll targets (children)

✔ Works with scroll snapping AND anchor navigation

✔ Logical properties that adapt to writing direction

📌 Why Logical Scroll Margins?

Logical properties (inline, block) adapt automatically to:

  • LTR & RTL languages
  • Vertical writing modes
  • Responsive layouts
Logical SideLTRRTL
inline-startleftright
inline-endrightleft
block-starttoptop
block-endbottombottom

📦 Syntax

scroll-margin-inline

scroll-margin-inline: <length> | <percentage>;

scroll-margin-block

scroll-margin-block: <length> | <percentage>;

🎨 1. Basic Examples

✨ A. Horizontal Snapping — scroll-margin-inline

Horizontal example

.slide {
  scroll-snap-align: start;
  scroll-margin-inline: 20px; /* margin on both inline edges */
}

This ensures the slide doesn’t touch the edges when snapped.

✨ B. Vertical Snapping — scroll-margin-block

Vertical example

.section {
  scroll-snap-align: start;
  scroll-margin-block: 50px; /* space above & below when scrolled */
}

🎨 2. Inline Start / End Versions

Inline start/end

.item {
  scroll-margin-inline-start: 30px;
  scroll-margin-inline-end: 10px;
}

Note

RTL languages flip inline direction automatically — no remapping needed.

🎨 3. Block Start / End Versions

Block start/end

.panel {
  scroll-margin-block-start: 80px; /* sticky header offset */
  scroll-margin-block-end: 20px;
}

Essential for anchor links that scroll too close to the top.

🎨 4. Fix Sticky Header and Anchor Issues

Sticky headers often hide anchor-linked sections. Add scroll margin to prevent this.

Sticky header fix

#contact {
  scroll-margin-block-start: 70px; /* matches header height */
}

🎨 5. Combine With scroll-snap-align & scroll-padding

Perfect snap control

.container {
  scroll-snap-type: y mandatory;
  scroll-padding-block: 40px;   /* container offset */
}

.section {
  scroll-snap-align: start;
  scroll-margin-block: 40px;    /* target offset */
}

This combination ensures precise and comfortable snapping behavior.

🧪 Real-World Use Cases

1️⃣ Carousels & Sliders

Carousel item

.card {
  scroll-margin-inline: 15px;
}

2️⃣ Documentation Navigation

Docs section

.doc-section {
  scroll-margin-block-start: 60px;
}

3️⃣ Mobile App Navigation with Full-Screen Snaps

App screens

.screen {
  height: 100vh;
  scroll-snap-align: start;
  scroll-margin-block: 50px;
}

⚠️ Common Mistakes

  • ❌ Using scroll-margin properties on the container instead of snap targets
  • ❌ Expecting scroll-margin to modify layout spacing (it does not)
  • ❌ Forgetting scroll-snap-type must be set on the container
  • ❌ Confusing scroll-margin with scroll-padding (target vs container)

Note

scroll-margin = offset for the element being scrolled into view
scroll-padding = offset for the scroll container

🔥 Summary

scroll-margin-inline and scroll-margin-block provide fine-grained, writing-mode–aware control over how elements are positioned during scroll snapping or anchor navigation. They ensure that content never snaps too close or gets hidden behind UI overlays.

>>“scroll-margin makes scroll targets land exactly where you want them—clean, precise, and predictable.”