Skip to content
SiteEmail

The scrollTo, scrollBy, and scroll methods scroll an element from JavaScript. With the smooth behavior, either from the behavior option of ScrollToOptions or from the scroll-behavior CSS property, the element animates to the new position instead of jumping. Prysm also fires the scroll and scrollend events so your UI can react while an element scrolls and when it stops.

Use smooth scrolling for UI such as lists, menus, and “back to top” buttons. The animation runs once per frame and updates the scroll position of the element on every tick.

  1. Scroll the element with scrollTo, scrollBy, or scroll and set the behavior option to smooth. Alternatively, set scroll-behavior: smooth on the scroll container and scroll it with scrollTo, scrollBy, scroll, scrollTop, or scrollLeft.
  2. Optionally, listen for the scroll and scrollend events.
<style>
#list {
height: 200px;
overflow-y: scroll;
scroll-behavior: smooth;
}
</style>
<div id="list">
<!-- Content taller than 200px -->
</div>
const list = document.getElementById('list');
list.addEventListener('scroll', () => console.log('scrolling', list.scrollTop));
list.addEventListener('scrollend', () => console.log('finished', list.scrollTop));
list.scrollTo({ top: 800, behavior: 'smooth' });

The element scrolls to 800px over a short animation. The scroll listener runs while the position changes, and the scrollend listener runs once when the animation finishes.

ValueBehavior
autoDefault. Scrolling jumps to the target position.
smoothScrolling animates to the target position.
  • The property is not inherited. Set it on the scroll container itself.
  • The property is not animatable.
  • Setting the property on body has no effect on its own. Scrolling body is forwarded to the html element, so set scroll-behavior on html.

When scroll-behavior is smooth, the following calls animate if they do not specify a behavior or specify auto:

  • scrollTo, scroll, and scrollBy.
  • Assigning scrollTop or scrollLeft.
  • Scrolling caused by the mouse wheel.

The behavior option of ScrollToOptions takes precedence over the CSS value. Passing behavior: 'smooth' animates even when the element has scroll-behavior: auto.

element.scrollTo({ top: 500, behavior: 'smooth' });

For more information, see the ScrollToOptions and Element API references.

The animation uses an ease-out curve. Its duration grows with the square root of the distance and is capped at 1500 ms. The cap cannot be changed.

The CSSOM View specification does not define a maximum duration. It requires only that a smooth scroll completes over a duration that the user agent defines.

  • A new smooth scroll replaces the one that is running. It starts from the current position.
  • A scroll with behavior: 'auto' on an element without scroll-behavior: smooth stops the running animation and jumps to the target position.
  • Requesting a smooth scroll to the current position does nothing and stops any running animation.
  • The target position is clamped to the scrollable range of the element.
  • scrollBy and scrollTo with only one coordinate use the target of the running animation as the starting point for the other axis, so consecutive calls accumulate correctly.
  • Destroying the element stops its animation.

Prysm supports the following scroll events:

EventWhen it fires
scrollThe scroll position of an element changed. During a smooth scroll, the event fires on every frame in which the position moved.
scrollendScrolling finished. A smooth scroll fires it once, after the animation reaches its target. An instant scroll fires it right after its scroll event.
  • Events are queued and dispatched once per frame, so several changes inside one frame produce a single event per element.
  • scroll events are dispatched before scrollend events.
  • Events caused by an event handler are dispatched on the next frame.
  • If 100 or more elements have a pending scroll event or a pending scrollend event in a frame, Prysm logs a performance hint warning in the content log. The events are still queued and dispatched.
  • Events fire only if the position changed and the element can scroll in that direction. For example, an element with overflow: hidden does not fire them.
  • scroll and scrollend events do not bubble, except when they fire on the html element. In that case, the event is dispatched on the document and bubbles to the window.
  • textarea elements also fire both events when their content scrolls.
  • If a smooth scroll is interrupted by another scroll, scrollend fires only when the last scroll finishes.

For the full list of supported events, see the JavaScript events table.

Prysm implements smooth scrolling with the following differences from desktop browsers:

  • Mouse wheel scrolling. Desktop browsers usually smooth mouse wheel scrolling by default. In Prysm, mouse wheel scrolling uses the auto behavior by default and is not smooth. It animates only when the scrolled element has scroll-behavior: smooth.
  • scrollIntoView. Prysm does not support scrollIntoView, so you cannot use it to scroll smoothly. Use scrollTo or scrollBy with the position of the target element instead.
  • Animation duration. The duration of a smooth scroll is defined by the user agent. Prysm uses the fixed timing described in Animation timing, which you cannot configure. Other browsers can use different timings.
  • Setting scroll-behavior on a parent and expecting a child to scroll smoothly. The property is not inherited.
  • Setting scroll-behavior on body. Use html instead.
  • Expecting scrollTop to read the target value right after a smooth scroll starts. It returns the current animated position.