CSSscroll-behavior & smooth scrolling

scroll-behavior & smooth scrolling

By default, when the browser jumps to a new scroll position — because the user clicked an anchor link like href="#section-2", called element.scrollIntoView(), or you programmatically set scrollTop — the jump is instant. The page teleports from one position to another with no visual continuity, which can feel jarring and makes it hard for the user to tell where on the page they landed. The scroll-behavior property fixes this with a single line of CSS: it tells the browser to animate scroll jumps smoothly instead of snapping to them instantly.
The property

Value

Effect

auto

Default — scroll jumps happen instantly

smooth

Scroll jumps are animated over a short, browser-defined duration

Applying it globally vs per-container
The most common approach is applying scroll-behavior: smooth once on the html element, which makes every scroll jump on the page smooth — anchor links, `scrollIntoView()` calls, and back/forward navigation to a fragment:

CSS
html {
  scroll-behavior: smooth;
}

You can also scope it to a single scrollable container instead of the whole document — useful when only one panel (a sidebar, a chat log, a code viewer) should animate its scroll jumps while the rest of the page behaves normally:

CSS
.sidebar-nav {
  scroll-behavior: smooth;
  overflow-y: auto;
  height: 100vh;
}
Worked example: smooth-scrolling anchor navigation

A typical use case is a table-of-contents page where clicking a link scrolls to a section further down the same page:

CSS
html {
  scroll-behavior: smooth;
  scroll-padding-top: 80px; /* offset for a fixed header */
}

HTML
<nav>
  <a href="#pricing">Pricing</a>
  <a href="#faq">FAQ</a>
</nav>

<section id="pricing">...</section>
<section id="faq">...</section>
Clicking either link now animates the scroll to the target section instead of jumping instantly, and scroll-padding-top keeps the section heading from disappearing underneath a fixed header when it lands.
It also affects JavaScript scrolling
scroll-behavior: smooth isn't limited to anchor links — it also governs any scroll triggered by element.scrollIntoView(), window.scrollTo(), and element.scrollTo(), as long as those calls don't explicitly override the behavior:

JS
// Inherits smooth behavior from the CSS property
document.querySelector('#faq').scrollIntoView()

// Explicitly overrides CSS to force instant, regardless of the property
window.scrollTo({ top: 0, behavior: 'instant' })

// Explicitly forces smooth even without the CSS property set
window.scrollTo({ top: 0, behavior: 'smooth' })
The JS behavior option always wins over the CSS property when both are specified
If a script explicitly passes behavior: 'auto' or behavior: 'instant', that call ignores scroll-behavior: smooth set in CSS. Omit the option (or rely on the property alone) to let CSS control it.
Respect prefers-reduced-motion
Smooth scrolling is a motion effect, and some users — often those with vestibular disorders that make sustained motion physically uncomfortable — have told their operating system they want reduced motion. Wrap the smooth behavior in a media query so it's only applied for users who haven't opted out. See prefers-reduced-motion for the full pattern:

CSS
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}
/* Users who prefer reduced motion silently fall back to instant jumps */
Next
Learn how to make a scroll container snap cleanly to each item as the user scrolls: Scroll Snap.