Skip to content

Tailwind CSS - Scroll Margin

The Scroll Margin utilities in Tailwind CSS allow you to control the margin around an element when it’s scrolled into view. This is crucial for creating polished user experiences, especially in layouts with fixed elements like sticky navigation bars.

Imagine a single-page website with a sticky header. When you click a navigation link to jump to a section (e.g., #about), the browser scrolls the top of the #about section directly to the top of the viewport. However, your sticky header will overlap the section’s title! Scroll margin solves this by creating an invisible ‘buffer zone’ at the top of the target element, ensuring it scrolls into view just below the header.

Tailwind provides a comprehensive set of utilities for applying scroll-margin on all sides or individual sides. Here are some of the most common ones. The full scale is available in the official documentation.

ClassCSS Properties
scroll-m-{amount}scroll-margin: {value};
scroll-mt-{amount}scroll-margin-top: {value};
scroll-mb-{amount}scroll-margin-bottom: {value};
scroll-ml-{amount}scroll-margin-left: {value};
scroll-mr-{amount}scroll-margin-right: {value};
scroll-mx-{amount}scroll-margin-left: {value}; scroll-margin-right: {value};
scroll-my-{amount}scroll-margin-top: {value}; scroll-margin-bottom: {value};
scroll-ms-{amount}scroll-margin-inline-start: {value}; (Logical property for start)
scroll-me-{amount}scroll-margin-inline-end: {value}; (Logical property for end)

The {amount} corresponds to Tailwind’s default spacing scale (e.g., 4 for 1rem, 16 for 4rem).

Practical Application: Fixing Navigation with a Sticky Header

Section titled “Practical Application: Fixing Navigation with a Sticky Header”

This example demonstrates the primary use case for scroll-margin. We have a sticky navigation bar at the top. Without scroll-mt-16, clicking the links would hide the section titles behind the nav bar. With scroll-mt-16 on each section, they snap into place perfectly below the header.

<!DOCTYPE html>
<html lang="en" class="scroll-smooth">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Scroll Margin with Sticky Header</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
/* For modern development, you'd typically install Tailwind via npm */
/* and build your CSS. The CDN is great for quick demos like this. */
</style>
</head>
<body class="bg-gray-100 text-gray-800">
<header class="bg-white/90 backdrop-blur-sm shadow-md sticky top-0 z-10">
<nav class="container mx-auto px-4 h-16 flex justify-center items-center space-x-8">
<a href="#section-1" class="hover:text-blue-600 transition-colors">Section 1</a>
<a href="#section-2" class="hover:text-blue-600 transition-colors">Section 2</a>
<a href="#section-3" class="hover:text-blue-600 transition-colors">Section 3</a>
</nav>
</header>
<main class="container mx-auto p-8 space-y-8">
<section id="section-1" class="scroll-mt-16 h-screen bg-blue-100 p-8 rounded-lg">
<h2 class="text-3xl font-bold">Section 1</h2>
<p class="mt-4">This section has a `scroll-mt-16` class (4rem), which matches the header's height, preventing its title from being hidden when you navigate to it.</p>
</section>
<section id="section-2" class="scroll-mt-16 h-screen bg-green-100 p-8 rounded-lg">
<h2 class="text-3xl font-bold">Section 2</h2>
<p class="mt-4">This section also has `scroll-mt-16` for proper alignment.</p>
</section>
<section id="section-3" class="scroll-mt-16 h-screen bg-yellow-100 p-8 rounded-lg">
<h2 class="text-3xl font-bold">Section 3</h2>
<p class="mt-4">The `scroll-smooth` class on the `<html>` tag provides a graceful scrolling animation.</p>
</section>
</main>
</body>
</html>

The same principle applies to horizontal scrolling. The scroll-mr-* or scroll-ml-* utilities can add a margin when an item snaps into place within a horizontal scroll container.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Horizontal Scroll Margin</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="p-8">
<h2 class="text-2xl font-bold mb-4">Horizontal Scroll Gallery</h2>
<div class="flex space-x-4 overflow-x-auto snap-x snap-mandatory p-4 bg-gray-200 rounded-lg">
<!-- Each item snaps to the start, but scroll-ml-4 adds an offset -->
<div class="snap-start scroll-ml-4 w-80 h-48 flex-shrink-0 bg-red-300 rounded-lg flex items-center justify-center font-bold text-xl">Card 1</div>
<div class="snap-start scroll-ml-4 w-80 h-48 flex-shrink-0 bg-blue-300 rounded-lg flex items-center justify-center font-bold text-xl">Card 2</div>
<div class="snap-start scroll-ml-4 w-80 h-48 flex-shrink-0 bg-green-300 rounded-lg flex items-center justify-center font-bold text-xl">Card 3</div>
<div class="snap-start scroll-ml-4 w-80 h-48 flex-shrink-0 bg-yellow-300 rounded-lg flex items-center justify-center font-bold text-xl">Card 4</div>
<div class="snap-start scroll-ml-4 w-80 h-48 flex-shrink-0 bg-purple-300 rounded-lg flex items-center justify-center font-bold text-xl">Card 5</div>
</div>
<p class="mt-4 text-gray-700">Notice the small margin on the left of each card as it snaps into place due to the `scroll-ml-4` utility.</p>
</body>
</html>
  • Combine with scroll-smooth: Use the scroll-smooth utility on the <html> or scrolling container for a better user experience.
  • Match offsets: Ensure your scroll margin value (e.g., scroll-mt-16) matches the height of your sticky element for pixel-perfect alignment.
  • Responsive Offsets: Use responsive variants like md:scroll-mt-20 if your sticky header changes height on different screen sizes.