JSFiddle - React, Tailwind, and code Playground

by web designer

HTML

<label for="overflow">This checkbox toggles <b>overflow: hidden</b> property on the gallery <br> to see the effect when a mask is applied:</label>
  <input type="checkbox" id="overflow">
  
  <div id="gallery"> <!-- mask -->
    
    <ul>  <!-- container -->
      <li><img src="http://dummyimage.com/96x96/f0f0f0/626262.png&text=1"></li>
      <li><img src="http://dummyimage.com/96x96/f0f0f0/626262.png&text=2"></li>
      <li><img src="http://dummyimage.com/96x96/f0f0f0/626262.png&text=3"></li>
      <li><img src="http://dummyimage.com/96x96/f0f0f0/626262.png&text=4"></li>
    </ul>    

  </div>
  
  <button type="button" id="prev">&laquo;</button>
  <button type="button" id="next">&raquo;</button>

CSS

#gallery {
   position: relative;
   width: 100px;
   height: 100px;
   border: 1px green dotted;
   margin: 30px 0 0 150px;
   /* usually an «overflow:hidden» is set here */
}

#overflow:checked + #gallery { 
  overflow:hidden; 
}

#gallery ul {
   font-size: 0;
   white-space: nowrap;
   position: absolute;
   top: 0;
   left: -100px;
   margin: 0; padding: 0;
}

#gallery li {
   display: inline-block;
   vertical-align: top;
   width: 96px;
   height: 96px;
   white-space: normal;
   padding: 2px
}

button {
  font: 40px "Courier New";
  border: 1px #d8d8d8 dotted;
  color: #626262;
  background: none;
  cursor: pointer;
  width: 50px;
  text-align: center;
  margin: 20px -150px 0 150px;
}

label, a {
   font: 14px Georgia;
   font-style: italic;
   color: #626262;
}

JavaScript

$(function() {
 
  var gallery = $('#gallery ul'),
      items   = gallery.find('li'),
      len     = items.length,
      current = 1,  /* the current item we're looking */
      
      first   = items.filter(':first'),
      last    = items.filter(':last'),
      
      triggers = $('button');
  
  /* 1. Cloning first and last item */
  first.before(last.clone(true)); 
  last.after(first.clone(true)); 
  
  /* 2. Set button handlers */
  triggers.on('click', function() {
    
    if (gallery.is(':not(:animated)')) {
     
        var cycle = false,
            delta = (this.id === "prev")? -1 : 1;
            /* in the example buttons have id "prev" or "next" */  
    
        gallery.animate({ left: "+=" + (-100 * delta) }, function() {
      
            current += delta;
       
            /** 
             * we're cycling the slider when the the value of "current" 
             * variable (after increment/decrement) is 0 or when it exceeds
             * the initial gallery length
             */          
            cycle = !!(current === 0 || current > len);
       
            if (cycle) {
                /* we switched from image 1 to 4-cloned or 
                   from image 4 to 1-cloned */
                current = (current === 0)? len : 1; 
                gallery.css({left:  -100 * current });
            }
        });   
     }
    
  });
});