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.

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:

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

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

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

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

11. Practice Exercise

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.