JSFiddle - React, Tailwind, and code Playground

by Ronny

HTML

<script src="https://rawgit.com/utatti/perfect-scrollbar/master/dist/perfect-scrollbar.js"></script>
<link rel="stylesheet" href="https://rawgit.com/utatti/perfect-scrollbar/master/css/perfect-scrollbar.css">
<div id="hideScroll">
  <div id="scrollable" class="outer">
    <div id="content" class="inner">
      Lorem ipsum dolor, sit amet consectetur adipisicing elit. Laudantium quos dolorum voluptatum, alias placeat modi illum itaque aspernatur ut, odio a neque facilis iure architecto tempore culpa amet velit. Eius.
    </div>
  </div>
</div>

<div id="scroller1" class="outer scrollbar">
  <div class="inner"></div>
</div>

<div id="scroller2" class="outer scrollbar">
  <div class="inner"></div>
</div>

<div id="scroller3" class="outer scrollbar">
  <div class="inner"></div>
</div>

<div id="scroller4" class="outer scrollbar">
  <div class="inner"></div>
</div>

CSS

:root {
  --container-width: 400px;
  --scrollable-width: 600px;
  --scrollable-height: 100px;
}

.inner {
  width: var(--scrollable-width);
  height: 10px;
}
.outer {
  width: var(--container-width);
  overflow-x: auto;
  height: 100%;
  position: relative;
}
#content {
  background: #88f;
  height: var(--scrollable-height);
}
#hideScroll {
  overflow: hidden;
}
#scroller1 {
  margin-top: 10px;
  transform: scaleX(.3);
  transform-origin: 0 0;
  border-radius: 10px 5px 2em / 20px 25px 30%;
}

#scroller2 {
  margin-top: 10px;
  transform-origin: 0 0;
}

#scroller3 {
  margin-top: 10px;
  transform: scaleX(2);
  transform-origin: 0 0;
}

#scroller4 {
  margin-top: 10px;
  transform: rotate(45deg);
  transform-origin: 0 100%;
}


.ps__rail-x {
  opacity: 1;
}

.ps__thumb-x {
  border-radius: 20px;
}
.ps__rail-x:hover .ps__thumb-x,
.ps__thumb-x {
  height: 12px;
  bottom: 3px;
}

JavaScript

var ps = new PerfectScrollbar('#scroller1.scrollbar');
var ps2 = new PerfectScrollbar('#scroller2.scrollbar');
var ps3 = new PerfectScrollbar('#scroller3.scrollbar');
var ps4 = new PerfectScrollbar('#scroller4.scrollbar');


// Get scrollbar size of current browser & os
const scrollHeight = scrollable.offsetHeight - content.offsetHeight
// Gett all scrollbar elements
const scrollbars = Array.from(document.querySelectorAll('.scrollbar'))

// Hide the scrollbar of content
hideScroll.style.height = `${content.offsetHeight}px`

scrollbars.forEach(scrollbar => {
  // Set custom scrollbar element height to be scrollbar height
  // Had to add '1' because chrome is weird with 0 height
  scrollbar.style.height = `${scrollHeight + 1}px`
  
  // Listen to both scrolls and change only if scroll is not equal
  scrollbar.addEventListener('scroll', syncScroll)
})

// Listen to main element scrolls and change only if scroll is not equal
scrollable.addEventListener('scroll', syncScroll)

function syncScroll(event) {
  if (scrollbars.some(scrollbar => scrollbar.scrollLeft !== scrollable.scrollLeft)) {
    scrollable.scrollTo(event.target.scrollLeft, 0)
    scrollbars.forEach(scrollbar => scrollbar.scrollTo(event.target.scrollLeft, 0))
  }
}


if (!scrollHeight) {
  document.body.innerHtml += 'Your scrollbars are hidden, you are probably on a mac with "auto" scrollbars'
}