Improve the Interaction to Next Paint by ditching JavaScript scrolling

Create a beautiful smooth scrolling experience that does not affect the Core Web Vitals

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-02-28

Replace JavaScript scrolling by CSS today

This blog has a bit of history to it. Until 2017 the only way to add consistent smooth scrolling behavior was to use a JavaScript library. And many developers did just that. The Core Web Vitals were not a thing yet and everyone was using jQuery as their main JavaScript library.

Now jump ahead to the current day. There are much better, faster and easier alternatives to JavaScript based anchor scrolling. However as a Core Web Vitals consultant I still see them every day.

Last reviewed by Arjen Karel on February 2026

Why JavaScript based scrolling is 'bad'

JavaScript based scrolling is bad for 2 reasons: it is complicated and it is slow.

Complicated: JavaScript based scrolling is unnecessarily complicated. You have to write and maintain hard to read code and even though the Window.scrollTo() method has made this code a lot easier it still is a lot harder to maintain than a single line of CSS.

Slow. JavaScript tends to block the main thread and is always slower than its CSS counterpart. Depending on how the scroll function was implemented it can block the main thread for quite some time and cause a major delay in the Interaction to Next Paint metric! According to the 2025 Web Almanac, mobile median Total Blocking Time sits at 1,916 milliseconds. Every unnecessary JavaScript function competing for the main thread makes that worse.

Why CSS Smooth Scrolling is 'good'

I talked about why JavaScript based scrolling is bad. The opposite is true for CSS based smooth scrolling. It really is as simple as adding the following to your stylesheet:

html{ scroll-behavior: smooth;}

Simple and effective

The CSS one-liner html { scroll-behavior: smooth; } is super simple to implement and more efficient than JavaScript-based solutions. This single line of code enables smooth scrolling for the entire page without any hard to maintain JavaScript functions. If you want to go further and defer or remove unnecessary JavaScript entirely, your INP processing time will thank you.

Better Performance

CSS-based smooth scrolling is handled natively by the browser and will in all cases outperform JavaScript implementations. This is especially important for optimizing the Interaction to Next Paint (INP) metric, since it will be less of a burden on the browser's main thread. JavaScript scroll handlers need to run on the main thread, and every millisecond spent there is a millisecond that delays the next user interaction. CSS scroll behavior runs off the main thread entirely. If you still have JavaScript that needs to run during interactions, read up on how to yield to the main thread.

Smooth anchor scrolling is just the start. CSS is taking over more scroll responsibilities that used to require JavaScript. Scroll-driven animations (Chrome 115+, Safari 26) let you tie animation progress to scroll position, replacing requestAnimationFrame scroll handlers entirely. Scroll-triggered animations (Chrome 145) fire time-based animations when crossing a scroll offset, replacing IntersectionObserver for reveal effects. And scroll-state container queries (Chrome 133+) let you style elements based on whether they are stuck, snapped, or scrollable, no JavaScript needed. The trend is clear: move scroll logic out of JavaScript and into CSS wherever you can.

Browser Compatibility

CSS smooth scrolling has 95% global browser support according to CanIUse. It has been baseline across all major browsers since March 2022. Old browsers, where smooth scrolling is not supported, simply fall back to the default direct jump to the anchor.

Easy Customization

CSS lets you easily customize the scroll behavior. For example the scroll-margin-top property lets you set the top distance to the scrolled element:

h1, h2, h3 {scroll-margin-top: 5rem;} 

Or even easier with the 'target' pseudo class

:target {scroll-margin-top: 5rem;} 

Respect motion preferences

Some users experience motion sickness from scroll animations. Wrapping your smooth scrolling in a prefers-reduced-motion media query ensures those users get instant jumps instead:

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

This applies smooth scrolling only for users who have not requested reduced motion. Users with vestibular disorders or motion sensitivity will see the default instant scroll.

Complete example

To see this code in action, simply click on the Table of Contents on the top of this page. You will notice a nice smooth scroll to the clicked anchor.

Here is a simplified example for you to copy and re-use

<html>

<head>
    <title>Smooth scroll to target</title>
    <style>
        html {
            scroll-behavior: smooth;
        }
        :target {
            scroll-margin-top: 5rem;
        }
        .largedivider {
            height: 1000px;
        }

    </style>

</head>

<body>
    <nav>
        <a href="#target">scroll to target</a>
    </nav>
    <div class="largedivider"> -- </div>
    <h2 id="target">scroll to me</h2>
    <div class="largedivider"> -- </div>
</body>

</html>

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

The RUM tool I built for my own clients.

CoreDash is what I use to audit enterprise platforms. Under 1KB tracking script, EU hosted, no consent banner. AI with MCP support built in. The same tool, available to everyone.

Create Free Account
Improve the Interaction to Next Paint by ditching JavaScript scrollingCore Web Vitals Improve the Interaction to Next Paint by ditching JavaScript scrolling