Dan Wiedenhoever
Dan Wiedenhoever

Reputation: 59

html horizontal scrolling with mousescrolling

I want a smooth horizontal scrolling with mousescrolling(mousewheel and touchpad)

I am only able to make it jump from position to position.

function transformScroll(event) {
  if (!event.deltaY) {
    return;
  }
  event.currentTarget.scrollLeft += event.deltaY + event.deltaX

  }

  var element = document.scrollingElement || document.documentElement;
  element.addEventListener('wheel', transformScroll);
.hs {
  position: absolute;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
  list-style: none;
}

.hs > li,
.item {
  border-right: #ffffff99 1px solid;
  width: 25vw;
  height: 100vh;
}

.item:last-child {
  border-right: unset;
}
<ul class="hs">
  <li class="item">test</li>
  <li class="item">test</li>
  <li class="item">test</li>
  <li class="item">test</li>
  <li class="item">test</li>
  <li class="item">test</li>
</ul>

I don't care if it is programmed in js or only css. We tried other js and css(for example rotated grids) approaches but didn't get a satisfying result.

Upvotes: 4

Views: 330

Answers (1)

Tobias Buschor
Tobias Buschor

Reputation: 3305

First, you need to prevent the default action: "scrolling down" for the wheel event using prefentDefault().
And since browsers have started to avoid to prevent this "default action" for performance reasons, you need to use {passive:false}

Then you can scroll there with scrollBy() and the option {behavior:'smooth'}.

Smooth is currently not supported by Safari, but there is a polyfill for that:
https://github.com/wessberg/scroll-behavior-polyfill

function transformScroll(event) {
  event.preventDefault();
  if (!event.deltaY) return;
  event.currentTarget.scrollBy({
    top: 0,
    left: event.deltaY + event.deltaX,
    behavior: 'smooth'
  });
}
var element = document.scrollingElement || document.documentElement;
element.addEventListener('wheel', transformScroll, {passive:false});
.hs {
  position: absolute;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
  list-style: none;
}

.hs > li,
.item {
  border-right: #ffffff99 1px solid;
  width: 25vw;
  height: 100vh;
}

.item:last-child {
  border-right: unset;
}
<ul class="hs">
  <li class="item">test</li>
  <li class="item">test</li>
  <li class="item">test</li>
  <li class="item">test</li>
  <li class="item">test</li>
  <li class="item">test</li>
</ul>

Upvotes: 1

Related Questions