JSFiddle - React, Tailwind, and code Playground

by Dan Shahin

HTML

<ul class="carousel">
  <li>Item Number 1</li>
  <li>Item Number 2</li>
  <li>Item Number 3</li>
  <li>Item Number 4</li>
</ul>

<a href="#" class="carousel-nav prev"><</a>
<a href="#" class="carousel-nav next">></a>

CSS

.carousel {
  position: relative;
  list-style: none;
}

.carousel > li {
  position: absolute;
}

.carousel > li:not(.active) {
  display: none;
}

@keyframes next-in {
  0% {
    opacity: 0;
    transform: translateY(50px);
  }
  100% {
    opacity: 1;
    transform: translateY(0px);
  }
}

@keyframes next-out {
  0% {
    opacity: 1;
    transform: translateX(0px);
  }
  100% {
    opacity: 0;
    transform: translateX(-50px);
  }
}

@keyframes prev-in {
  0% {
    opacity: 0;
    transform: translateX(-50px);
  }
  100% {
    opacity: 1;
    transform: translateX(0px);
  }
}

@keyframes prev-out {
  0% {
    opacity: 1;
    transform: translateY(0px);
  }
  100% {
    opacity: 0;
    transform: translateY(50px);
  }
}
.carousel > li.next-in {
  animation: next-in 0.5s;
}

.carousel > li.next-out {
  animation: next-out 0.5s;
}

.carousel > li.prev-in {
  animation: prev-in 0.5s;
}

.carousel > li.prev-out {
  animation: prev-out 0.5s;
}

JavaScript

var currentIndex = 0,
    itemCount    = $('.carousel > li').length;

/* add the active class to the first item to hide all the others */
$('.carousel > li:eq(' + currentIndex + ')').addClass('active');

$('.carousel-nav').on('click', function() {
    var $active  = $('.carousel > li.active'),
        isNext   = $(this).hasClass('next');
    $active.on('animationEnd', function() {
      $active.removeClass('active next-out prev-out');
      $active.off('animationEnd');
        console.log('animationend active');
    });
    currentIndex = (currentIndex + (isNext ? 1 : -1)) % itemCount;
    
    /* go back to the last item if we hit -1 */
    if (currentIndex === -1) {
        currentIndex = itemCount - 1;
    }
    
    var $next = $('.carousel > li:eq(' + currentIndex + ')');
    
    
    $next.on('animationEnd', function() {
      $next.removeClass('next-in prev-in');
      $next.off('animationend');
        console.log('animationEnd next');
    });
    
    
    
    $active.addClass(isNext ? 'next-out' : 'prev-out');
    $next.addClass('active').addClass(isNext ? 'next-in' : 'prev-in');
    
    
    
    return false;
});