Spotify Style Mobile-friendly Horizontal Scroller In jQuery

Spotify Style Mobile-friendly Horizontal Scroller In jQuery
File Size: 7.17 KB
Views Total:
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   

A responsive, flexible, touch-enabled, horizontal scroller/slider/carousel inspired by Spotify.com. Based on jQuery, flexbox and CSS3 transforms.

The horizontal scroller allows your visitors to scroll through a group of web content using mouse drag, arrow-click, and touch swipe events. Supports unlimited instances on the same page.

How to use it:

1. Add web content as list items together with the header and navigation arrows to the webpage.

<div class="hs__wrapper">
  <div class="hs__header">
    <h2 class="hs__headline">My Scroller</h2>
    <div class="hs__arrows">
      <a class="arrow disabled arrow-prev"></a>
      <a class="arrow arrow-next"></a>
    </div>
  </div>
  <ul class="hs">
    <li class="hs__item"> 
      <div class="hs__item__image__wrapper">
        <img class="hs__item__image" src="1.jpg" alt=""/>
      </div>
      <div class="hs__item__description">
        <span class="hs__item__title">Title 1</span>
        <span class="hs__item__subtitle">Subtitle 1</span>
      </div>
    </li>
    <li class="hs__item"> 
      <div class="hs__item__image__wrapper">
        <img class="hs__item__image" src="2.jpg" alt=""/>
      </div>
      <div class="hs__item__description">
        <span class="hs__item__title">Title 2</span>
        <span class="hs__item__subtitle">Subtitle 2</span>
      </div>
    </li>
    <li class="hs__item"> 
      <div class="hs__item__image__wrapper">
        <img class="hs__item__image" src="3.jpg" alt=""/>
      </div>
      <div class="hs__item__description">
        <span class="hs__item__title">Title 3</span>
        <span class="hs__item__subtitle">Subtitle 3</span>
      </div>
    </li>
    ... more content here ...
  </ul>
</div>

2. The necessary CSS/CSS3 rules for the scroller.

* {
  box-sizing: border-box;
}

::-webkit-scrollbar {
  /* Webkit */
  width: 0;
  height: 0;
}

.hs {
  display: flex;
  overflow-x: scroll;
  justify-content: space-between;
  scrollbar-width: none;
  /* Firefox */
  -ms-overflow-style: none;
  /* IE 10+ */
  -webkit-overflow-scrolling: touch;
  margin: 0 -20px;
}

.hs__header {
  display: flex;
  align-items: center;
  width: 100%;
}

.hs__headline {
  flex: 1;
}

.hs__arrows {
  align-self: center;
}

.hs__arrows .arrow:before {
  content: '';
  display: inline-block;
  vertical-align: middle;
  content: "";
  background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNSIgaGVpZ2h0PSI5IiB2aWV3Qm94PSIwIDAgMTUgOSI+Cgk8cGF0aCBmaWxsPSIjMzMzMzMzIiBkPSJNNy44NjcgOC41NzRsLTcuMjItNy4yMi43MDctLjcwOEw3Ljg2NyA3LjE2IDE0LjA1Ljk4bC43MDYuNzA3Ii8+Cjwvc3ZnPgo=");
  background-size: contain;
  -webkit-filter: brightness(5);
          filter: brightness(5);
  width: 18px;
  height: 12px;
  cursor: pointer;
}

.hs__arrows .arrow.disabled:before {
  -webkit-filter: brightness(2);
          filter: brightness(2);
}

.hs__arrows .arrow.arrow-prev:before {
  -webkit-transform: rotate(90deg);
          transform: rotate(90deg);
  margin-right: 10px;
}

.hs__arrows .arrow.arrow-next:before {
  -webkit-transform: rotate(-90deg);
          transform: rotate(-90deg);
}

.hs__item {
  flex-grow: 1;
  flex-shrink: 0;
  flex-basis: calc(25% - 10px * 2 - 5px);
  margin: 10px;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  position: relative;
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
}

.hs__item:last-child:after {
  content: "";
  display: block;
  position: absolute;
  width: 10px;
  height: 1px;
  right: calc(10px * 2 * -1);
}

.hs__item:first-child {
  margin-left: calc(10px * 2);
}

.hs__item__description {
  z-index: 1;
  align-self: flex-start;
  margin: 10px 0;
}

.hs__item__subtitle {
  color: #aaa;
  display: block;
}
.hs__item__image__wrapper {
  position: relative;
  width: 100%;
  height: 0;
  padding-bottom: 100%;
}

.hs__item__image {
  pointer-events: none;
  position: absolute;
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
     object-fit: cover;
}

@media (hover: none) and (pointer: coarse) {
  .hs__wrapper .hs__arrows {
    display: none;
  }
  .hs__wrapper .hs__item {
    flex: 1 0 calc(23% - 10px * 2);
  }
}

@media only screen and (hover: none) and (pointer: coarse) and (max-width: 990px) {
  .hs__wrapper .hs__item {
    flex: 1 0 calc(45% - 10px * 2);
  }
}

3. Include the latest version of jQuery JavaScript library on the page.

<script src="/path/to/jquery.min.js"></script>

4. The core JavaScript (jQuery script) to activate the scroller. Copy and paste the following JavaScript snippets into the document (after jQuery) and done.

var instance = $(".hs__wrapper"), x;
$.each( instance, function(key, value) {
    
    var arrows = $(instance[key]).find(".arrow"),
        box = $(instance[key]).find(".hs"), x,
        mx = 0,
        maxScrollWidth = box[0].scrollWidth - box[0].clientWidth / 2 - 10;
    
  $(arrows).on('click', function() {
      
    if ($(this).hasClass("arrow-next")) {
      x = ((box.width() / 2)) + box.scrollLeft() - 10;
      box.animate({
        scrollLeft: x,
      })
      if(x < maxScrollWidth - (box.width() / 2)) {
       $(this).prev().removeClass('disabled');
      } else {
       $(this).addClass('disabled');
      }
    } else {
      x = ((box.width() / 2)) - box.scrollLeft() -10;
      box.animate({
        scrollLeft: -x,
      })
      if(x > -10) {
        $(this).addClass('disabled');
      } else {
        $(this).next().removeClass('disabled');
      }
    }
      
  });
    
  $(box).on({
    mousemove: function(e) {
      var mx2 = e.pageX - this.offsetLeft;
      if(mx) this.scrollLeft = this.sx + mx - mx2;
    },
    mousedown: function(e) {
      this.sx = this.scrollLeft;
      mx = e.pageX - this.offsetLeft;
    }
  });

  $(document).on("mouseup", function(){
    mx = 0;
  });
    
});

This awesome jQuery plugin is developed by Kilian So. For more Advanced Usages, please check the demo page or visit the official website.