CSS scroll-behavior and Smooth Scrolling Explained
The scroll-behavior property controls whether scrolling happens instantly or with a smooth animated transition. It is most often used to make in-page anchor links and programmatic scrolling feel more polished and easier to follow.
Quick answer: Use scroll-behavior: smooth on a scroll container or the root element to animate supported scrolling actions. Use auto if you want the browser’s default instant scrolling.
Difficulty: Beginner
You'll understand this better if you know: basic CSS selectors, how overflow creates scrollable containers, and how anchor links work.
1. What Is scroll-behavior?
scroll-behavior is a CSS property that tells the browser how to move a scrollable area when scrolling is triggered by navigation or by a supported API. It does not change the layout of the page; it only changes the motion used when the scroll position updates.
- auto means the browser scrolls immediately.
- smooth means the browser animates the scroll motion.
- It can be set on the document root or on an element that scrolls.
- It is especially useful for anchor links and jump links.
2. Why scroll-behavior Matters
Instant jumps can make a page feel abrupt, especially when a user clicks a table of contents link or when a page moves to an error field or section. Smooth scrolling helps the user keep context because they can see where the page is moving.
It matters most when:
- you have long pages with section links,
- you want a more polished navigation experience,
- you are styling a fixed-height container that scrolls internally,
- you want scrolling behavior to be consistent across supported browser actions.
It is less useful when immediate movement is clearer, such as in some admin interfaces or situations where users need rapid jumps with no animation.
3. Basic Syntax or Core Idea
The property has a very small syntax surface. You assign it to a scroll container and choose either instant or smooth motion.
Minimal example
This example enables smooth scrolling for the whole page by applying the property to the root element.
html {
scroll-behavior: smooth;
}Here, html is the scroll container for the document in most cases, and smooth tells the browser to animate supported scrolling actions.
Supported values
- auto — default scrolling behavior.
- smooth — animated scrolling.
If you remove the property entirely, the browser behaves as though auto is in effect.
4. Step-by-Step Examples
Example 1: Smooth scrolling for anchor links
When a user clicks a link like #contact, the browser scrolls to the matching element. With smooth, that movement is animated.
html {
scroll-behavior: smooth;
}
nav a {
text-decoration: none;
}
section#contact {
scroll-margin-top: 5rem;
}This is the classic use case for the property. The scroll animation makes it easier to follow the jump to the target section.
Example 2: A scrollable panel inside a page
Any element with overflow that creates a scroll container can use scroll-behavior.
.messages {
max-height: 20rem;
overflow-y: auto;
scroll-behavior: smooth;
}In this case, the panel itself scrolls smoothly when the browser or another feature moves to a position inside it.
Example 3: Switching back to instant scrolling
Sometimes you want to explicitly cancel smooth scrolling, such as in a dense application interface.
html {
scroll-behavior: auto;
}This tells the browser to use the normal immediate scroll behavior instead of animating the movement.
Example 4: Combining smooth scrolling with fixed headers
If your page has a sticky header, the target section can end up hidden behind it. scroll-behavior handles the animation, while scroll-margin-top helps position the target correctly.
html {
scroll-behavior: smooth;
}
h2 {
scroll-margin-top: 6rem;
}This combination improves both motion and visibility. The page moves smoothly, and the heading is not hidden under the fixed bar.
5. Practical Use Cases
- Table of contents links on documentation pages.
- Jump links in single-page sites and landing pages.
- Scrollable side panels, chat panes, and message lists.
- Anchor-based navigation in long-form articles.
- Interface flows where the browser scrolls to a highlighted section after validation.
6. Common Mistakes
Mistake 1: Expecting smooth scrolling for every kind of movement
scroll-behavior only affects supported browser scrolling actions. It does not animate every change to an element’s position.
Problem: Developers often expect CSS to animate manual layout changes, but this property only changes how scrolling itself behaves.
html {
scroll-behavior: smooth;
}
.panel {
top: 200px;
}Fix: Use scroll-behavior for scrolling and a different CSS animation or transition for position changes.
html {
scroll-behavior: smooth;
}
.panel {
transition: top 0.3s ease;
}The fixed version separates scroll motion from layout animation, which is how the browser treats these features.
Mistake 2: Setting it on a non-scrolling element
The property has no visible effect if the element never scrolls. Beginners often place it on a container that does not actually manage overflow.
Problem: The CSS is valid, but nothing changes because the element is not a scroll container.
.card {
scroll-behavior: smooth;
}Fix: Apply it to the element that actually scrolls, and make sure overflow creates scrolling.
.card {
max-height: 18rem;
overflow-y: auto;
scroll-behavior: smooth;
}Once the element can scroll, the property has a real target to control.
Mistake 3: Ignoring reduced-motion preferences
Some users prefer less motion, and smooth scrolling can feel uncomfortable or distracting. In those cases, honoring user preference is more important than animation.
Problem: Always forcing smooth scrolling can conflict with accessibility preferences and create a worse experience for motion-sensitive users.
html {
scroll-behavior: smooth;
}Fix: Respect the user’s reduced-motion preference and switch to instant scrolling in that case.
html {
scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
}This approach keeps the enhancement for most users while avoiding unnecessary motion for people who asked for less animation.
7. Best Practices
1. Apply it to the right scroll container
For page-wide anchor navigation, the root element is usually the best place. For internal panes, set it on the element that actually scrolls.
html {
scroll-behavior: smooth;
}
.sidebar {
overflow-y: auto;
scroll-behavior: smooth;
}This keeps the rule close to the element whose scrolling you want to control.
2. Pair it with scroll-margin for anchor targets
Smooth motion does not solve offset problems caused by headers. Use scroll-margin-top on target headings so the destination is visible after the scroll ends.
h2 {
scroll-margin-top: 4rem;
}This makes section jumps clearer and avoids the common “my heading is hidden” complaint.
3. Respect reduced-motion preferences
Users who prefer reduced motion should get a calmer experience. That usually means keeping the smooth effect as an enhancement, not as a requirement.
@media (prefers-reduced-motion: reduce) {
html,
.sidebar {
scroll-behavior: auto;
}
}This keeps your CSS inclusive without removing the enhancement for everyone else.
8. Limitations and Edge Cases
- Browser support is good in modern browsers, but very old browsers may ignore smooth and fall back to instant scrolling.
- The property affects scrolling initiated by supported browser features, not every possible visual movement on the page.
- It does not solve fixed-header overlap by itself; you usually need scroll-margin or related offset techniques.
- If another rule sets scroll-behavior: auto later in the cascade, your smooth setting may appear to “stop working.”
- Nested scroll containers can be confusing because the page may scroll smoothly while an inner container still scrolls differently.
- Some users expect it to animate when using keyboard focus changes or custom interactions, but behavior can vary depending on how the scroll is triggered.
9. Practical Mini Project
Here is a small documentation page with a table of contents, anchored sections, and smooth scrolling enabled on the page root. This is a complete pattern you can adapt to long content pages.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Smooth Scrolling Demo</title>
</head>
<body>
<nav>
<a href="#introduction">Introduction</a>
<a href="#details">Details</a>
<a href="#contact">Contact</a>
</nav>
<main>
<section id="introduction">
<h2>Introduction</h2>
<p>This section explains the topic.</p>
</section>
<section id="details">
<h2>Details</h2>
<p>This section contains longer content.</p>
</section>
<section id="contact">
<h2>Contact</h2>
<p>This section shows the final destination.</p>
</section>
</main>
</body>
</html>To make the page smooth and account for a fixed header, add the CSS below.
html {
scroll-behavior: smooth;
}
h2 {
scroll-margin-top: 4rem;
}This example shows the most common real-world use: smooth navigation between named sections on a long page.
10. Key Points
- scroll-behavior controls how scrolling moves, not what content is shown.
- smooth animates supported scroll actions; auto uses instant scrolling.
- It works on the scroll container, often the root html element for full-page navigation.
- It is useful for anchor links, long pages, and internal scroll panels.
- It does not replace offsets for sticky headers or motion-friendly accessibility handling.
11. Practice Exercise
- Create a long page with at least four sections and a small navigation menu at the top.
- Enable smooth scrolling for the page.
- Add a fixed or sticky header, then make sure section headings are not hidden when linked.
- Use a reduced-motion media query so the page switches back to instant scrolling when needed.
Expected result: Clicking the navigation links should glide to the selected section, while users who prefer less motion get instant jumps.
Hint: Apply scroll-behavior to html, then use scroll-margin-top on the headings inside each target section.
html {
scroll-behavior: smooth;
}
h2 {
scroll-margin-top: 4rem;
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
}12. Final Summary
scroll-behavior is a small CSS property with a very practical job: it controls whether scrolling is instant or smooth. In most projects, smooth is best for anchor links and other deliberate navigation because it helps users follow movement across long pages.
The most important things to remember are to apply it to the correct scroll container, combine it with offset techniques when you have fixed headers, and respect reduced-motion preferences. If you keep those points in mind, scroll-behavior becomes an easy and reliable way to improve scrolling UX without adding script or complexity.
Next, learn scroll-margin and overflow together with this property, since they are the most common companions in real layouts.