AI CSS Scroll Behavior — Smooth Scrolling for Modern Web Navigation

Published February 23, 2026 · 9 min read · Design

Clicking an anchor link and having the page teleport instantly to the target section feels jarring. Users lose their sense of position on the page, and the abrupt jump breaks the flow of reading. The CSS scroll-behavior property fixes this with a single line of code, turning harsh jumps into smooth, animated scrolls that help users maintain spatial awareness.

Before scroll-behavior existed, smooth scrolling required JavaScript libraries or custom animation code. Today, one CSS declaration handles it natively in every modern browser — no dependencies, no bundle size increase, and no JavaScript execution cost.

Enabling Smooth Scrolling with One Line

The simplest implementation applies smooth scrolling to the entire page:

html {
  scroll-behavior: smooth;
}

That is it. Every anchor link click, every element.scrollIntoView() call, and every navigation to a URL with a hash fragment now scrolls smoothly instead of jumping. The browser handles the animation timing, easing curve, and duration automatically.

The property accepts two values:

You can apply it to any scrollable container, not just the root html element:

/* Smooth scroll on the whole page */
html {
  scroll-behavior: smooth;
}

/* Smooth scroll inside a specific container */
.scrollable-panel {
  overflow-y: auto;
  scroll-behavior: smooth;
  max-height: 500px;
}

/* Smooth scroll for a horizontal carousel */
.carousel {
  overflow-x: auto;
  scroll-behavior: smooth;
  display: flex;
  gap: 16px;
}
Pro tip: Apply scroll-behavior: smooth to the html element, not body. The scrolling container for the main document is the viewport, which is controlled by the html element in most browsers.

Fixing the Sticky Header Problem with scroll-margin

If your site has a fixed or sticky navigation bar, smooth scrolling to an anchor will scroll the target element behind the header. The content you wanted to see is hidden under the nav. This is the most common complaint about anchor navigation, and scroll-margin solves it elegantly:

/* Fixed header height is 64px */
.sticky-nav {
  position: sticky;
  top: 0;
  height: 64px;
  z-index: 100;
}

/* Add scroll margin to all section targets */
section[id] {
  scroll-margin-top: 80px; /* header height + 16px breathing room */
}

/* Or target specific heading elements */
h2[id], h3[id] {
  scroll-margin-top: 80px;
}

The scroll-margin-top property creates invisible spacing above the element that the scroll position accounts for. When the browser scrolls to a section with scroll-margin-top: 80px, it stops 80 pixels before the element's top edge — exactly where you want it when a sticky header is present.

Dynamic Header Heights

If your header height changes between breakpoints, use CSS custom properties to keep the scroll margin in sync:

:root {
  --header-height: 64px;
  --scroll-offset: calc(var(--header-height) + 16px);
}

@media (max-width: 768px) {
  :root {
    --header-height: 48px;
  }
}

section[id] {
  scroll-margin-top: var(--scroll-offset);
}

This pattern ensures your scroll targets always clear the header regardless of screen size. For more techniques on managing responsive layouts, see our CSS media query breakpoints guide.

Building a Table of Contents with Smooth Scroll

A table of contents with smooth scrolling is one of the most user-friendly navigation patterns for long-form content. Here is a complete implementation:

<!-- Table of contents -->
<nav class="toc" aria-label="Table of contents">
  <h2>On this page</h2>
  <ul>
    <li><a href="#introduction">Introduction</a></li>
    <li><a href="#getting-started">Getting Started</a></li>
    <li><a href="#advanced">Advanced Techniques</a></li>
    <li><a href="#conclusion">Conclusion</a></li>
  </ul>
</nav>

<!-- Content sections -->
<section id="introduction">...</section>
<section id="getting-started">...</section>
<section id="advanced">...</section>
<section id="conclusion">...</section>
html {
  scroll-behavior: smooth;
}

section[id] {
  scroll-margin-top: 80px;
}

.toc {
  position: sticky;
  top: 80px;
}

.toc a {
  display: block;
  padding: 8px 16px;
  color: #8888a0;
  border-left: 2px solid transparent;
  transition: all 0.2s;
}

.toc a:hover,
.toc a.active {
  color: #00cec9;
  border-left-color: #00cec9;
}

For generating table of contents markup automatically, check out our AI table of contents generator guide.

Scroll Behavior with JavaScript

While CSS scroll-behavior handles anchor links automatically, JavaScript gives you more control for programmatic scrolling. The scrollIntoView() method respects the CSS scroll-behavior setting, but you can also override it per call:

// Uses CSS scroll-behavior setting
document.getElementById('target').scrollIntoView();

// Explicitly smooth, regardless of CSS setting
document.getElementById('target').scrollIntoView({
  behavior: 'smooth',
  block: 'start',    // vertical alignment
  inline: 'nearest'  // horizontal alignment
});

// Scroll to top button
document.querySelector('.back-to-top').addEventListener('click', () => {
  window.scrollTo({
    top: 0,
    behavior: 'smooth'
  });
});

The block parameter controls vertical alignment: start aligns the element's top with the viewport top, center centers it vertically, and end aligns the bottom. The inline parameter does the same for horizontal scrolling.

Scroll to Top Button Pattern

A back-to-top button that appears after scrolling down is a natural companion to smooth scrolling:

.back-to-top {
  position: fixed;
  bottom: 24px;
  right: 24px;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(108, 92, 231, 0.9);
  backdrop-filter: blur(8px);
  color: white;
  border: none;
  cursor: pointer;
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.3s, transform 0.3s;
  z-index: 50;
}

.back-to-top.visible {
  opacity: 1;
  transform: translateY(0);
}

The button uses backdrop-filter: blur() for a frosted glass look that matches modern dark mode interfaces. For more on backdrop-filter techniques, see our frosted glass UI patterns guide.

Accessibility and Reduced Motion

Smooth scrolling animations can cause discomfort for users with vestibular disorders or motion sensitivity. The prefers-reduced-motion media query lets you disable smooth scrolling for users who have requested reduced motion in their operating system settings:

html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  /* Also disable other scroll-related animations */
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
  }
}
Accessibility note: Always include the prefers-reduced-motion override when using scroll-behavior: smooth. Approximately 25-30% of users have motion sensitivity settings enabled on their devices. Respecting this preference is not optional — it is a core accessibility requirement.

For JavaScript-triggered scrolling, check the preference programmatically:

const prefersReducedMotion = window.matchMedia(
  '(prefers-reduced-motion: reduce)'
).matches;

element.scrollIntoView({
  behavior: prefersReducedMotion ? 'auto' : 'smooth'
});

Combining scroll-behavior with scroll-snap

The scroll-behavior and scroll-snap properties work together to create polished scrolling experiences. While scroll-behavior controls the animation style, scroll-snap controls where scrolling stops:

.fullpage-sections {
  overflow-y: auto;
  scroll-behavior: smooth;
  scroll-snap-type: y mandatory;
  height: 100vh;
}

.fullpage-sections section {
  scroll-snap-align: start;
  height: 100vh;
  scroll-margin-top: 0;
}

This creates a full-page scrolling experience where each section snaps into place with a smooth animation. For a deep dive into scroll-snap techniques, read our CSS scroll-snap guide.

Performance and Browser Support

CSS scroll-behavior: smooth has excellent browser support in 2026, working in all modern browsers including Chrome, Firefox, Safari, and Edge. The browser handles the animation on the compositor thread, so it does not block the main thread or cause jank.

A few performance considerations to keep in mind:

Smooth Scrolling as a Foundation

CSS scroll-behavior is one of those properties that delivers outsized UX improvement for minimal code investment. One line of CSS transforms every anchor link on your page from a jarring teleport into a smooth, oriented navigation experience. Pair it with scroll-margin for sticky headers, scroll-snap for section-based layouts, and prefers-reduced-motion for accessibility, and you have a complete scrolling system built entirely in CSS.

Build scroll-snapping layouts visually
Design scroll-snap containers with smooth scrolling, configure snap points and alignment, and export production-ready CSS for carousels, galleries, and full-page sections.
Try AI CSS Scroll Snap Generator →

The AI CSS Scroll Snap Generator lets you visually configure scroll-snap containers with smooth scrolling behavior. Set snap points, alignment, and scroll-margin offsets, then export the complete CSS with accessibility-friendly prefers-reduced-motion overrides included automatically.