Controlling smooth scrolling in browsers

Posted . Visible to the public.

It can be hard to understand what causes a browser scroll smoothly or instantly. CSS, JavaScript and the browser settings all have options to influence the scroll behavior. They all interact with each other and sometimes use the same words for different behavior.

CSS

Scrolling elements can use the scroll-behavior CSS property to express a preference between smooth and instant scrolling.

Preferring instant scrolling

CSS can prefer instant scrolling behavior:

html {
  scroll-behavior: auto; /* the default */
}

An auto behavior causes the browser to instantly jump to new scroll positions in these situations:

  • When clicking an <a href="#hash">.
  • When JavaScript functions scroll without a { behavior } option.
  • When the user manually changes the location #hash in the address bar

The auto behavior can still cause smooth scrolling in some situations:

  • When user scrolls using her mouse wheel or PgUp / PgDn keys. This can be disabled in the browser settings, but is usually enabled by default.
  • When a JavaScript function overrides the CSS property with an explicit { behavior } option.

Tip

There is no scroll-behavior: instant property that can force instant scrolling in all sitations.

Preferring smooth scrolling

CSS can prefer a smooth scrolling animation:

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

An smooth behavior causes the browser to animate scrolling in these situations:

  • When clicking an <a href="#hash">.
  • When JavaScript functions scroll without a { behavior } option.
  • When the user manually changes the location #hash in the address bar

The smooth behavior can still cause instant scrolling in some situations:

  • When the user has explicitly disabled scroll animations in their browser settings.
  • When a JavaScript function overrides the CSS property with an explicit { behavior } option.

JavaScript

There are multiple JavaScript functions that scroll an element with overflowing content:

All these functions accept a { behavior } option that controls whether the scrolling will be animated:

document.scrollingElement.scrollTo({ top: 500, behavior: 'smooth' })

This { behavior } option always overrides a scroll-behavior CSS property.

Scrolling instantly

To force instant scrolling, pass a { behavior: 'instant' } option:

document.scrollingElement.scrollTo({ top: 500, behavior: 'instant' })

This always jumps instantly to the scroll position, even with a scroll-behavior: smooth style, and even with scroll animations enabled in the browser settings.

Note

Confusingly, this option used to be called { behavior: 'auto' }. You may still find outdated documentation for this.

Scrolling smoothly

To force smooth scrolling in most situations, pass a { behavior: 'smooth' } option:

document.scrollingElement.scrollTo({ top: 500, behavior: 'smooth' })

This animates the scroll motion scroll position, even with a scroll-behavior: auto style.

The only exception where { behavior: 'smooth' } does not animate is when the user has disabled smooth scrolling in her browser settings.

Delegating scroll behavior to CSS

Scrolling functions can delegate the scroll behavior to the scroll-behavior style. The option for that is confusingly named { behavior: 'auto' }. This will animate smoothly with scroll-behavior: smooth, but jump instantly with scroll-behavior: auto:

document.scrollingElement.scrollTo({ top: 500, behavior: 'auto' })

The 'auto' behavior is also the default Show archive.org snapshot , so you can omit the { behavior } property to the same effect:

document.scrollingElement.scrollTo({ top: 500 })

Instead of using a scrolling functions, scripts can set the scroll position by mutating the { scrollLeft, scrollTop } properties of any scrolling element. This will also use the scroll-behavior style, just like scrolling with { behavior: 'auto' }:

document.scrollingElement.scrollTop = 500
Henning Koch
Last edit
Henning Koch
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2025-04-30 09:12)