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;
});