JSFiddle - React, Tailwind, and code Playground

by brombomb

HTML

<nav class="slider-bar__wrapper">
  <ul class="slider-bar">
    <li class="slider-bar__item"><button class="slider-bar__button" onClick="setSliderLinePosition(this)">Metaphysics</button></li>
    <li class="slider-bar__item"><button class="slider-bar__button" onClick="setSliderLinePosition(this)">Joe Dispenza</button></li>
    <li class="slider-bar__item"><button class="slider-bar__button" onClick="setSliderLinePosition(this)">Documentaries</button></li>
    <li class="slider-bar__item"><button class="slider-bar__button" onClick="setSliderLinePosition(this)">Sacred Geometry</button></li>
    <li class="slider-bar__item"><button class="slider-bar__button" onClick="setSliderLinePosition(this)">Sacred Sites</button></li>
    <li class="slider-bar__item"><button class="slider-bar__button" onClick="setSliderLinePosition(this)">Psychedelic Perspectives</button></li>
    <li class="slider-bar__item"><button class="slider-bar__button" onClick="setSliderLinePosition(this)">Meditation</button></li>
    <li class="slider-bar__item"><button class="slider-bar__button" onClick="setSliderLinePosition(this)">Universal Consciousness</button></li>
    <li class="slider-bar__item"><button class="slider-bar__button" onClick="setSliderLinePosition(this)">Ancient Egypt</button></li>
    <li class="slider-bar__item"><button class="slider-bar__button" onClick="setSliderLinePosition(this)">Fractal Geometry</button></li>
    <li class="slider-bar__item"><button class="slider-bar__button" onClick="setSliderLinePosition(this)">Afterlife</button></li>
    <li class="slider-bar__item"><button class="slider-bar__button" onClick="setSliderLinePosition(this)">Energy Healing</button></li>
    <li class="slider-bar__slider" style="top: 22px; left: 0px; width: 95px;"></li>
  </ul>
</nav>

SCSS

body {
  font-family: "Source Sans Pro", Sans-Serif;
}

.slider-bar {
  position: relative;
  margin-bottom: 0;
  padding: 0 5px;
  display: inline-block;
  white-space: nowrap;
  overflow-x: hidden;
  overflow-y: hidden;
  padding-left: 0;
  margin-top: 15px;
  z-index: 1;
  list-style: none;

  &__wrapper {
    position: relative;
    display: flex;

    ::-webkit-scrollbar {
      width: 0 !important;
    }

    overflow: -moz-scrollbars-none;
    -ms-overflow-style: none;
    height: 40px;
    align-items: center;
  }

  &__item {
    display: inline-block;
  }

  &__button {
    font-size: 16px;
    margin-right: 25px;
    color: CornFlowerBlue;
    padding: 3px;
    border: none;
    text-align: left;
    background-color: initial;
    cursor: pointer;

    &:active,
    &:focus,
    &:hover {
      color: #000;
      outline: none;
    }

    &.active {
      color: #000;
      border-bottom: 4px solid CornFlowerBlue;
      font-weight: 900;
      border-bottom-width: 0;
    }
  }

  &__slider {
    position: absolute;
    width: 7%;
    border-bottom: 4px solid CornFlowerBlue;
    margin: 0;
    background-color: transparent;
    z-index: 0;
    height: 0;
    /* transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); */
    /* transition: all 0.5s ease-in-out; */

    transition: left 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55),
      width 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55),
      transform 0.05s cubic-bezier(0.68, -0.55, 0.265, 1.55);

    &.moving {
      transform: scale(1.15, 1);
      transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
    }
    
  }
}

JavaScript

setSliderLinePosition = ref => {
  const sliderRef = document.getElementsByClassName("slider-bar__slider")[0];

  const left = ref.offsetLeft
  const right = ref.offsetRight
  const width = ref.offsetWidth
  const height = ref.offsetHeight - 4
  const curLeft = sliderRef.offsetLeft
  const stretchWidth = width * 1
  
  let dir = 1; // right is positive
  if(left < curLeft) {
  dir = -1; // moving 
  }

  sliderRef.style.top = `${height}px`
  sliderRef.style.left = `${left}px`
  sliderRef.style.right = `${right}px`
  sliderRef.style.width = `${stretchWidth}px`

  sliderRef.classList.add('moving')
  setTimeout(() => {
    //sliderRef.style.width = `${width}px`
    sliderRef.classList.remove('moving')
  }, 500) // set this timeout to the transition duration
}