Horizontal scrollable menu

Horizontal scrollable menu

by pj_js15

HTML

<div class="pn-ProductNav_Wrapper">
<nav id="pnProductNav" class="pn-ProductNav">
    <div id="pnProductNavContents" class="pn-ProductNav_Contents">
        <a href="#" class="pn-ProductNav_Link" aria-selected="true">Chairs</a>
        <a href="#" class="pn-ProductNav_Link">Tables</a>
        <a href="#" class="pn-ProductNav_Link">Cookware</a>
        <a href="#" class="pn-ProductNav_Link">Beds</a>
        <a href="#" class="pn-ProductNav_Link">Desks</a>
        <a href="#" class="pn-ProductNav_Link">Flooring</a>
        <a href="#" class="pn-ProductNav_Link">Lighting</a>
        <a href="#" class="pn-ProductNav_Link">Mattresses</a>
        <a href="#" class="pn-ProductNav_Link">Solar Panels</a>
        <a href="#" class="pn-ProductNav_Link">Bookcases</a>
        <a href="#" class="pn-ProductNav_Link">Mirrors</a>
        <a href="#" class="pn-ProductNav_Link">Rugs</a>  
        <a href="#" class="pn-ProductNav_Link">Curtains &amp; Blinds</a>  
        <a href="#" class="pn-ProductNav_Link">Frames &amp; Pictures</a>  
        <a href="#" class="pn-ProductNav_Link">Wardrobes</a>  
        <a href="#" class="pn-ProductNav_Link">Storage</a>  
        <a href="#" class="pn-ProductNav_Link">Decoration</a>  
        <a href="#" class="pn-ProductNav_Link">Appliances</a>
		  <a href="#" class="pn-ProductNav_Link">Racks</a>
        <a href="#" class="pn-ProductNav_Link">Worktops</a>
	<span id="pnIndicator" class="pn-ProductNav_Indicator"></span>
    </div>
</nav>
	<button id="pnAdvancerLeft" class="pn-Advancer pn-Advancer_Left" type="button">
		<svg class="pn-Advancer_Icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 551 1024"><path d="M445.44 38.183L-2.53 512l447.97 473.817 85.857-81.173-409.6-433.23v81.172l409.6-433.23L445.44 38.18z"/></svg>
	</button>
	<button id="pnAdvancerRight" class="pn-Advancer pn-Advancer_Right" type="button">
		<svg class="pn-Advancer_Icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 551 1024"><path d="M105.56 985.817L553.53 512 105.56...

CSS

* {
  box-sizing: inherit;
}

.pn-ProductNav_Wrapper {
  position: relative;
  padding: 0 11px;
  box-sizing: border-box;
}

.pn-ProductNav {
  /* Make this scrollable when needed */
  overflow-x: auto;
  /* We don't want vertical scrolling */
  overflow-y: hidden;
  /* For WebKit implementations, provide inertia scrolling */
  -webkit-overflow-scrolling: touch;
  /* We don't want internal inline elements to wrap */
  white-space: nowrap;
  /* If JS present, let's hide the default scrollbar */
  /* positioning context for advancers */
  position: relative;
  font-size: 0;
}
.js .pn-ProductNav {
  /* Make an auto-hiding scroller for the 3 people using a IE */
  -ms-overflow-style: -ms-autohiding-scrollbar;
  /* Remove the default scrollbar for WebKit implementations */
}
.js .pn-ProductNav::-webkit-scrollbar {
  display: none;
}

.pn-ProductNav_Contents {
  float: left;
  transition: -webkit-transform .2s ease-in-out;
  transition: transform .2s ease-in-out;
  transition: transform .2s ease-in-out, -webkit-transform .2s ease-in-out;
  position: relative;
}

.pn-ProductNav_Contents-no-transition {
  transition: none;
}

.pn-ProductNav_Link {
  text-decoration: none;
  color: #888;
  font-size: 1.2rem;
  font-family: -apple-system, sans-serif;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  border: 1px solid transparent;
  padding: 0 11px;
}
.pn-ProductNav_Link + .pn-ProductNav_Link {
  border-left-color: #eee;
}
.pn-ProductNav_Link[aria-selected="true"] {
  color: #111;
}

.pn-Advancer {
  /* Reset the button */
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  background: transparent;
  padding: 0;
  border: 0;
  /* Now style it as needed */
  position: absolute;
  top: 0;
  bottom: 0;
  /* Set the buttons invisible by default */
  opacity: 0;
  transition: opacity .3s;
}
.pn-Advancer:focus {
  outline: 0;
}
.pn-Advancer:hover {
  cursor: pointer;
}

.pn-Advancer_Left {
  left: 0;
}
[data-overflowing="both"]...

JavaScript

var SETTINGS = {
    navBarTravelling: false,
    navBarTravelDirection: "",
	 navBarTravelDistance: 150
}

var colours = {
    0: "#867100",
    1: "#7F4200",
    2: "#99813D",
    3: "#40FEFF",
    4: "#14CC99",
    5: "#00BAFF",
    6: "#0082B2",
    7: "#B25D7A",
    8: "#00FF17",
    9: "#006B49",
    10: "#00B27A",
    11: "#996B3D",
    12: "#CC7014",
    13: "#40FF8C",
    14: "#FF3400",
    15: "#ECBB5E",
    16: "#ECBB0C",
    17: "#B9D912",
    18: "#253A93",
    19: "#125FB9",
}

document.documentElement.classList.remove("no-js");
document.documentElement.classList.add("js");

// Out advancer buttons
var pnAdvancerLeft = document.getElementById("pnAdvancerLeft");
var pnAdvancerRight = document.getElementById("pnAdvancerRight");
// the indicator
var pnIndicator = document.getElementById("pnIndicator");

var pnProductNav = document.getElementById("pnProductNav");
var pnProductNavContents = document.getElementById("pnProductNavContents");

pnProductNav.setAttribute("data-overflowing", determineOverflow(pnProductNavContents, pnProductNav));

// Set the indicator
moveIndicator(pnProductNav.querySelector("[aria-selected=\"true\"]"), colours[0]);

// Handle the scroll of the horizontal container
var last_known_scroll_position = 0;
var ticking = false;

function doSomething(scroll_pos) {
    pnProductNav.setAttribute("data-overflowing", determineOverflow(pnProductNavContents, pnProductNav));
}

pnProductNav.addEventListener("scroll", function() {
    last_known_scroll_position = window.scrollY;
    if (!ticking) {
        window.requestAnimationFrame(function() {
            doSomething(last_known_scroll_position);
            ticking = false;
        });
    }
    ticking = true;
});


pnAdvancerLeft.addEventListener("click", function() {
	// If in the middle of a move return
    if (SETTINGS.navBarTravelling === true) {
        return;
    }
    // If we have content overflowing both sides or on the left
    if (determineOverflow(pnProductNavContents,...