Search code examples
javascripthtmlcssscrollsmooth-scrolling

Mobile-like scrolling for desktops


Mobile touch-screen scrolling works really smoothly out of the box in modern browsers. For example, if you swipe fast across the div, it keeps scrolling for a little while, gradually reducing its' speed, after you release your finger from the screen. This way, you can reach the desired div scroll position a lot more efficiently.

Here's my snippet with a simple div consisting of 50 child items:

const App = () => {


  let data = []

  for (let i = 0; i < 50; i++) {
    data.push({
      key: i,
      value: `item ${i}`
    })
  }

  const renderItem = (x) => {
    return (
      'hello' + x.key
    )
  }

  return ( <
    div className = "tileView" > {
      data.map((x, i) => {
        return ( <
          div key = {
            i
          }
          className = "item" > {
            renderItem(x)
          } <
          /div>
        );
      })
    } <
    /div>
  );
};

ReactDOM.render( < App / > , document.getElementById('root'));
.tileView {
  display: flex;
  overflow-x: scroll;
  overflow-y: hidden;
  width: 600px;
}

.item {
  border: 1px solid gray;
  width: 100px;
  height: 100px;
  flex-shrink: 0;
  margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

I want to find a solution that would make that div scrollable on mouse drag, matching the behavior of touch and drag scrolling.

I have tried implementing this solution. It's working, however, it's not perfect, as the page scroll immediately stops on the mouse-up event.

Ideally, I'm looking for a solution that would implement mobile scrolling behavior on desktops.

Not sure if I'm thinking in the right direction, but maybe it's possible to add an event to a div that would make the browser think that the div is touched rather than clicked?

If not, what would be the best approach to resolve this?


Solution

  • I think what you're looking for is momentum based drag scrolling. You can see a good example in the codepen provided in the answer to this question. Hopefully that helps :)