DEV Community

Cover image for Smooth Scroll on Mobile
Jesse Wei
Jesse Wei

Posted on

Smooth Scroll on Mobile

The Problem

Smooth scrolling on mobile devices is key to good user experience, though I think we all have experienced delayed or blocked scrolling behaviors.

The Cause

Event handlers may call preventDefault() to cancel default behaviours. In our case, the browser does not know if preventDefault() will be called before the touch handler finishes executing. So it waits for the handler to finish before triggering the scroll which is why we experience the delay.

The Solution

Fortunately this can be avoided by setting the passive option of relevant event listeners to true like this:

document.addEventListener(touchstart, handler, {passive: true})
Enter fullscreen mode Exit fullscreen mode

To solve the problem, we need to tell the browser beforehand that the scroll will not be cancelled so that it does not wait for the handler to finish running. And this is exactly what passive: true does.

Notes

Default Value

According to mdn,

If not specified, defaults to false – except that in browsers other than Safari and Internet Explorer, defaults to true for the wheel, mousewheel, touchstart and touchmove events.

There are two takeaways here:

  • On modern browsers like Chrome (version 56 or later),
document.addEventListener(touchstart, handler)
Enter fullscreen mode Exit fullscreen mode

is equal to

document.addEventListener(touchstart, handler, {passive: true})
Enter fullscreen mode Exit fullscreen mode
  • passive: true is only applied to handlers for these events: wheel, mousewheel, touchstart and touchmove.

Prevent Scrolling

In some cases where we DO want to prevent scrolling (e.g. Google Map or other interactive iframes), we can easily cancel it by setting the following in CSS:

touch-action: none;
Enter fullscreen mode Exit fullscreen mode

References

Top comments (0)