Horizontal Smooth Momentum Scrolling

I've published an API on github that can easily solve this problem, below you'll find the code to do what you want.

Compared to yours I've just added the js code and the <script> in the HTML.

If you want to know more about it, here you can find the documentation.

Since the requirements have changed a little bit and the API has been updated I've modified the example below so that it better fits the question.

Main changes to the answer:

  • Now the js is inside a init() method called onload
  • The css styles have been modified (transform:rotate brakes most of scrolling APIs)
  • The support for the navbar's smooth scroll has been added
  • The scrolling amount now depends on how much the user physically scrolls the mousewheel

function init() {
     * Variables preparation
    let yourWrapperElement = document.getElementsByClassName("outer-wrapper")[0];
    let minScrollDistance = window.innerWidth / 5; //Adjust the scroll sensitivity as you like
    let minScrollDistanceRaw = minScrollDistance / 3;
    let whateverEaseFunctionYouWant = remaningScrollDistance => { return remaningScrollDistance / 15 + 1 };
    let previousScrollDirection = undefined;
    let currentScrollDirection = undefined;

    //Added support for navbar menu's smooth scrolling

     * As you asked for, we only apply the custom scrolling for desktop devices
     * by using the "wheel" event instead of the "scroll" or "touchmove" events.
    yourWrapperElement.addEventListener("wheel", event => {
       * We want to overwrite the default scrolling behaviour
       * of your outer-wrapper component.
       * In this new section we check if the scrolling has changed currentScrollDirection
       * and if so we stop the scrolling on the exact spot the user decided
      currentScrollDirection = Math.sign(event.deltaY);
      if(currentScrollDirection !== previousScrollDirection) {
        previousScrollDirection = currentScrollDirection;

      //The scrolling amount is now influenced by how much the user scrolls
      if(Math.abs(event.deltaY) >= 100) //For browsers that use multiples of 100 as deltaY
          uss.scrollXBy(event.deltaY / 100 * minScrollDistance, yourWrapperElement, null, true);
      else //For the browsers that use the raw scroll input as deltaY
          uss.scrollXBy(event.deltaY * minScrollDistanceRaw, yourWrapperElement, null, true);     
    }, {passive:false});

     * We apply a the custom ease function
     * which will be used whenever our component is scrolled by the API
    uss.setXStepLengthCalculator(whateverEaseFunctionYouWant, yourWrapperElement);
body {
  margin: 0;
  padding: 0;

.outer-wrapper {
  width: auto;
  height: 100vh; /*  Changed to vh */
  width: 100vw; /* Added */
  /*transform: rotate(-90deg) translateX(-100vh); ROTATING containers brakes 90% of scrolling APIs
  transform-origin: top left;*/
  overflow-y: scroll;
  overflow-x: hidden;
  position: absolute;
  scrollbar-width: none;
  -ms-overflow-style: none;
  /*scroll-behavior: smooth; ISN'T NEEDED FOR MY API */

::-webkit-scrollbar {
  display: none;

.wrapper {
  display: flex;
  flex-direction: row;
  transform: rotate(90deg) translateY(-100vh); ROTATING containers brakes 90% of scrolling APIs
  transform-origin: top left;*/
  margin: 0; /* not really needed */
  padding: 0; /* not really needed */

.section {
  color: #000;
  flex-shrink: 0; /* ADDED insted of the width/height of the wrapper */
  width: 100vw;
  height: 100vh;

#a { background-color: #ccc; }
#b { background-color: #fff; }
#c { background-color: #ccc; }
#d { background-color: #fff; }
#e { background-color: #ccc; }
#f { background-color: #fff; }

h2 {
  text-align: center;
  font-size: 200px;
  margin: 0;

/* MENU  _________________________ */

.logo {
  float: left;

nav {
  width: 100%;

/* HEADER */

header {
  float: left;
  width: 100%;
  position: absolute;
  z-index: 9999;


header.large {
  height: 50px;

header.large .logo {
  width: 225px;
  height: 50px;
  margin: 20px 0 0 20px;
  background: url('../images/logo-fireqa-green-500px.png');
  background-repeat: no-repeat;
  background-size: contain;

  transition: 0.7s all;
  -moz-transition: 0.7s all;
  -webkit-transition: 0.7s all;
  -o-transition: 0.7s all;


header.large ul {
  list-style: none;
  float: right;
  margin-right: 25px;
header.small ul {
  list-style: none;
  float: right;
  margin: 0;

header.large li {
  display: inline;
  float: left;
  list-style-position: inside;
  height: 50px;
  -webkit-transition: all ease 0.3s;
  -moz-transition: all ease 0.3s;
  transition: all 0.3s ease-in-out;

header.large li a {
  display: block;
  padding: 20px;
  color: #0E6245;
  text-decoration: none;
  font-family: 'Montserrat', 'arial', sans-serif;
  font-weight: 600 !important;
  letter-spacing: -1px;
  font-size: 25px;

  background-image: linear-gradient(#0E6245, #0E6245);
  background-position: 50% 80%;
  background-repeat: no-repeat;
  background-size: 0% 4px;

  -moz-transition: all 0.3s ease-in-out 0s;
  -ms-transition: all 0.3s ease-in-out 0s;
  -o-transition: all 0.3s ease-in-out 0s;
  -webkit-transition: all 0.3s ease-in-out 0s;
  transition: all 0.3s ease-in-out 0s;

header.large li a:hover, a:focus {
  background-size: 60% 4px;
  <script src = "https://raw.githack.com/CristianDavideConte/universalSmoothScroll/master/js/universalsmoothscroll-min.js"></script>
<body onload = init()>

<main class="outer-wrapper">
    <div class="wrapper">
        <article class="section" id="a"><h2>01</h2></article>
        <article class="section" id="b"><h2>02</h2></article>
        <article class="section" id="c"><h2>03</h2></article>
        <article class="section" id="d"><h2>04</h2></article>
        <article class="section" id="e"><h2>05</h2></article>
        <article class="section" id="f"><h2>06</h2></article>

<!-- MENU _____________________ -->

<header class="large">
    <div class="container">
        <a href="#welcome"><div class="logo"></div></a>
            <li><a href="#a">01</a></li>
            <li><a href="#b">02</a></li>
            <li><a href="#c">03</a></li>
            <li><a href="#d">04</a></li>