Scrolling with the scrollTo API and smooth scrolling
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.
How to make use of the feature
Section titled “How to make use of the feature”- Scroll the element with
scrollTo,scrollBy, orscrolland set thebehavioroption tosmooth. Alternatively, setscroll-behavior: smoothon the scroll container and scroll it withscrollTo,scrollBy,scroll,scrollTop, orscrollLeft. - Optionally, listen for the
scrollandscrollendevents.
<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.
Feature details
Section titled “Feature details”The scroll-behavior property
Section titled “The scroll-behavior property”| Value | Behavior |
|---|---|
auto | Default. Scrolling jumps to the target position. |
smooth | Scrolling 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
bodyhas no effect on its own. Scrollingbodyis forwarded to thehtmlelement, so setscroll-behavioronhtml.
Which scrolling is smooth
Section titled “Which scrolling is smooth”When scroll-behavior is smooth, the following calls animate if they do not specify a behavior or specify auto:
scrollTo,scroll, andscrollBy.- Assigning
scrollToporscrollLeft. - 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' });Animation timing
Section titled “Animation timing”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.
Interrupting and combining scrolls
Section titled “Interrupting and combining scrolls”- A new smooth scroll replaces the one that is running. It starts from the current position.
- A scroll with
behavior: 'auto'on an element withoutscroll-behavior: smoothstops 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.
scrollByandscrollTowith 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.
Scroll events
Section titled “Scroll events”Prysm supports the following scroll events:
| Event | When it fires |
|---|---|
scroll | The scroll position of an element changed. During a smooth scroll, the event fires on every frame in which the position moved. |
scrollend | Scrolling 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.
scrollevents are dispatched beforescrollendevents.- Events caused by an event handler are dispatched on the next frame.
- If 100 or more elements have a pending
scrollevent or a pendingscrollendevent 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: hiddendoes not fire them. scrollandscrollendevents do not bubble, except when they fire on thehtmlelement. In that case, the event is dispatched on thedocumentand bubbles to thewindow.textareaelements also fire both events when their content scrolls.- If a smooth scroll is interrupted by another scroll,
scrollendfires only when the last scroll finishes.
For the full list of supported events, see the JavaScript events table.
Differences from browsers
Section titled “Differences from browsers”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
autobehavior by default and is not smooth. It animates only when the scrolled element hasscroll-behavior: smooth. scrollIntoView. Prysm does not supportscrollIntoView, so you cannot use it to scroll smoothly. UsescrollToorscrollBywith 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.
Common mistakes
Section titled “Common mistakes”- Setting
scroll-behavioron a parent and expecting a child to scroll smoothly. The property is not inherited. - Setting
scroll-behavioronbody. Usehtmlinstead. - Expecting
scrollTopto read the target value right after a smooth scroll starts. It returns the current animated position.
© 2026 Coherent Labs. All rights reserved.