From ca2b750e6131cf37848ab50f9e690937a28d1622 Mon Sep 17 00:00:00 2001 From: Leopold Tal G Date: Thu, 3 Nov 2022 23:57:01 +1100 Subject: [PATCH] fix: Scroll instantly when the user prefers reduced motion Smooth scrolling can trigger seasickness for some users. The [`prefers-reduced-motion` media query](https://css-tricks.com/introduction-reduced-motion-media-query/) allows these users to specify an accessibility setting for less animation, e.g. instant scrolling. --- src/core/event/scroll.js | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/core/event/scroll.js b/src/core/event/scroll.js index bd6661918..77086f2e6 100644 --- a/src/core/event/scroll.js +++ b/src/core/event/scroll.js @@ -16,18 +16,33 @@ function scrollTo(el, offset = 0) { } enableScrollEvent = false; - scroller = new Tweezer({ - start: window.pageYOffset, - end: - Math.round(el.getBoundingClientRect().top) + window.pageYOffset - offset, - duration: 500, - }) - .on('tick', v => window.scrollTo(0, v)) - .on('done', () => { + const scrollEnd = + Math.round(el.getBoundingClientRect().top) + window.pageYOffset - offset; + const reduceMotion = window.matchMedia( + '(prefers-reduced-motion: reduce)' + ).matches; + + if (reduceMotion) { + // User wants reduced motion: scroll instantly + setTimeout(() => { + window.scrollTo(0, scrollEnd); enableScrollEvent = true; scroller = null; + }); + } else { + // Scroll smoothly + scroller = new Tweezer({ + start: window.pageYOffset, + end: scrollEnd, + duration: 500, }) - .begin(); + .on('tick', v => window.scrollTo(0, v)) + .on('done', () => { + enableScrollEvent = true; + scroller = null; + }) + .begin(); + } } function highlight(path) {