The CSS scroll-behavior property
The CSS scroll-behavior property controls how the page moves to a scroll target. The default, auto, jumps instantly; scroll-behavior: smooth animates the scroll, so clicking an anchor link glides to the section. Set it on the html element — and pair it with a reduced-motion check for users who prefer no animation.
Overview
scroll-behavior decides whether scrolling to a target happens in a single jump or as a smooth animation. With the default auto, clicking an in-page anchor or calling a scroll method snaps straight to the destination. Set scroll-behavior: smooth and the same action glides there instead.
It replaces a once-common chunk of JavaScript. A single rule on the html element — html { scroll-behavior: smooth; } — gives every same-page anchor link a smooth scroll, and it also applies to programmatic scrolling like element.scrollIntoView(). No libraries, no event handlers.
One responsibility comes with it. Smooth scrolling is motion, and some people find motion disorienting or nauseating, so it should respect the prefers-reduced-motion setting. The clean approach is to enable smooth scrolling only inside @media (prefers-reduced-motion: no-preference), so users who have asked for less motion keep the instant jump.
Syntax
html {
scroll-behavior: smooth;
}
/* respect users who prefer less motion */
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
}
Values
The scroll-behavior property accepts the values below. Every property also accepts the CSS-wide keywords inherit, initial, revert and unset.
| Value | Description |
|---|---|
auto |
Jumps instantly to the scroll target. The default. |
smooth |
Animates scrolling to anchors and programmatic scrolls. |
Example
<style>
.scroller { scroll-behavior: smooth; height: 130px; overflow-y: auto; border: 1px solid #d0d7e2; border-radius: 10px; font: 14px system-ui, sans-serif; }
.scroller section { padding: 16px; min-height: 110px; }
.scroller a { color: #1c7ce9; }
#s1 { background: #eff6ff; } #s2 { background: #f5f3ff; } #s3 { background: #ecfdf5; }
</style>
<div class="scroller">
<section id="s1">Section one. <a href="#s3">Jump to three (smoothly)</a></section>
<section id="s2">Section two.</section>
<section id="s3">Section three. <a href="#s1">Back to one</a></section>
</div>
Best practices
- Set
scroll-behavior: smoothon thehtmlelement so all same-page anchor links scroll smoothly. - Disable it inside a
prefers-reduced-motion: reduceblock for users who have asked to limit motion. - Pair it with
scroll-margin-topon anchor targets so a sticky header does not cover the heading you scroll to. - It also affects
scrollIntoView(), so you can drop the JavaScript smooth-scroll polyfill entirely.
Accessibility
Smooth scrolling is animated motion, and for people with vestibular conditions, animated movement of the whole viewport can cause dizziness or nausea. Because of that, it should honor the user's prefers-reduced-motion setting rather than being forced on everyone.
The simplest pattern is to gate it: turn scroll-behavior: smooth off inside @media (prefers-reduced-motion: reduce) so those users get an instant jump. Also make sure the scroll still works for keyboard users — the destination should receive focus where appropriate so the next Tab continues from the right place, not back at the top.
Frequently asked questions
How do I enable smooth scrolling in CSS?
scroll-behavior: smooth on the html element. Same-page anchor links and programmatic scrolls then animate instead of jumping.Do I still need JavaScript for smooth scrolling?
scroll-behavior: smooth handles anchor links and scrollIntoView() on its own, so the old JavaScript smooth-scroll code is no longer needed.How do I stop a sticky header covering the scrolled-to heading?
scroll-margin-top to the target elements, roughly equal to the header height, so they stop below it.Should smooth scrolling respect reduced motion?
@media (prefers-reduced-motion: reduce) so people who prefer less motion get an instant jump instead of an animation.