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:
-
Element.prototype.scrollTo()
Show archive.org snapshot -
Element.prototype.scrollBy()
Show archive.org snapshot -
Element.prototype.scrollIntoView()
Show archive.org snapshot
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