You can horizontally scroll my demo page by pressing Space Bar, Page Up / Page Down and Left Arrow / Right Arrow keys. You can also snap scroll with a mouse or trackpad.
But only one or the other works.
Is there a way that keyboard events and CSS scroll snapping can coexist? What am I missing? Any help would be really appreciated, since I’ve been struggling with this problem for over a week.
Check out my demo on CodePen
(Please uncomment the relevant piece of CSS code to enable the scroll snapping effect in order to see that keyboard shortcuts stop working.)
import animate from "https://cdn.jsdelivr.net/npm/animateplus@2/animateplus.js"
const sections = Array.from(document.querySelectorAll("section")).sort(
(s1, s2) => {
return s1.getBoundingClientRect().left - s2.getBoundingClientRect().left
}
)
const getSectionInView = () => {
const halfWidth = window.innerWidth / 2
const index = sections.findIndex(
section =>
section.getBoundingClientRect().left <= halfWidth &&
section.getBoundingClientRect().right > halfWidth
)
return index
}
const getNextSection = dir => {
const sectionInViewIndex = getSectionInView()
const nextIndex = sectionInViewIndex + dir
const numSections = sections.length
const nextSectionIndex =
nextIndex < 0 || nextIndex >= numSections ? sectionInViewIndex : nextIndex
return sections[nextSectionIndex]
}
const container = document.scrollingElement
const animateScroll = dir => {
const from = container.scrollLeft
const { left } = getNextSection(dir).getBoundingClientRect()
return progress => (container.scrollLeft = from + progress * left)
}
window.onload = () => {
document.body.onkeydown = event => {
switch (event.key) {
case " ": // Space Bar
case "PageDown":
case "ArrowRight": {
animate({
easing: "out-quintic",
change: animateScroll(1)
})
break
}
case "PageUp":
case "ArrowLeft": {
animate({
easing: "out-quintic",
change: animateScroll(-1)
})
break
}
}
}
}
Note: I’m using a small and elegant module called Animate Plus for achieving the smooth scrolling animation.
Update: @Kostja’s solution works in Chrome, but not in Safari for Mac or iOS, and it’s crucial to me that it works in Safari.
CSS Scroll Snap is supported in all major browsers. A previous version of the specification was implemented in some browsers, and may appear in tutorials and articles. If material includes the deprecated scroll-snap-points-x and scroll-snap-points-y properties, it should be considered outdated.
The scroll-snap-align property specifies the box's snap position as an alignment of its snap area (as the alignment subject) within its snap container's snapport (as the alignment container). The two values specify the snapping alignment in the block axis and inline axis, respectively.
I guess there is not, the css overwrites the javascript. But you can simply add wheel eventlistener like:
window.addEventListener("wheel", function() {
if(event.deltaY > 0){
animate({
easing: "out-quintic",
change: animateScroll(1)
})
}
if(event.deltaY < 0){
animate({
easing: "out-quintic",
change: animateScroll(-1)
})
}
});
https://codepen.io/kostjaaa/pen/NWWVBKd
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With