DEV Community

Cover image for How to create horizontal scroll with mouse wheel using JavaScript
Juan Belieni
Juan Belieni

Posted on

How to create horizontal scroll with mouse wheel using JavaScript

Native horizontal scroll with mouse wheel is not so trivial for the user. However, this behavior can be changed using an event listener.

In fact, there are some events involving scrolling and mouse wheel such as mousewheel and DOMMouseScroll. But here I will be using the wheel event.

So, to accomplish this behavior, the JavaScript code will look like this:

element.addEventListener('wheel', (event) => {
  event.preventDefault();

  element.scrollBy({
    left: event.deltaY < 0 ? -30 : 30,
  });
});
Enter fullscreen mode Exit fullscreen mode

Where element is the HTML element that the user will scroll by.

But you can ask why left has static values. That's because different browsers will provide different values for event.deltaY. So it's better to put just one value, only varying when the element is being scrolled to one side or the other.

Result:

Discussion (3)

Collapse
jonrandy profile image
Jon Randy

I think this sort of thing is generally a bad idea. The only good use case I've seen is in those scrolling timeline style stories sometimes found on news sites - where progress through the story is advanced by 'scrolling' down (even though sometimes the scrolling might stop or change direction). With these sites though, it's always quite clear that scrolling 'down' will advanced you through the story, and scrolling up will 'rewind'.

Having this kind of interaction as part of a 'normal' interface is generally quite a jarring experience

Collapse
moopet profile image
Ben Sinclair

Why would you want to associate one hand movement with a different axis? And how does this behave with a touchpad or screen, where you'd be swiping from side-to-side?

Collapse
juanbelieni profile image
Juan Belieni Author

I've tested it with a screen, and it works well. But you're right, when user moves side-to-side with touchpad, it doesn't work, because of the preventDefault. When I have the time, I will update the post to include this information. Thanks!