<div class="container">
<div class="carousel slide multi-item-carousel" id="theCarousel">
<div class="carousel-inner row w-100 mx-auto">
<div class="carousel-item active col-md-4">
<img src="https://via.placeholder.com/300/f44336/000000?text=1" class="img-fluid mx-auto d-block">
</div>
<div class="carousel-item col-md-4">
<img src="https://via.placeholder.com/300/e91e63/000000?text=2" class="img-fluid mx-auto d-block">
</div>
<div class="carousel-item col-md-4">
<img src="https://via.placeholder.com/300/9c27b0/000000?text=3" class="img-fluid mx-auto d-block">
</div>
<div class="carousel-item col-md-4">
<img src="https://via.placeholder.com/300/673ab7/000000?text=4" class="img-fluid mx-auto d-block">
</div>
<div class="carousel-item col-md-4">
<img src="https://via.placeholder.com/300/4caf50/000000?text=5" class="img-fluid mx-auto d-block">
</div>
<div class="carousel-item col-md-4">
<img src="https://via.placeholder.com/300/8bc34a/000000?text=6" class="img-fluid mx-auto d-block">
</div>
<div class="carousel-item col-md-4">
<img src="https://via.placeholder.com/300/ffffff/000000?text=7" class="img-fluid mx-auto d-block">
</div>
<div class="carousel-item col-md-4">
<img src="https://via.placeholder.com/300/000000/ffffff?text=8" class="img-fluid mx-auto d-block">
</div>
</div>
<a class="carousel-control-prev" href="#theCarousel" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#theCarousel" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
// Developed at agap2
// Slider based on Google's #1 result:
// https://codepen.io/mephysto/pen/ZYVKRY
// And on the RESPONSIVE alternative:
// http://www.codeply.com/go/s3I9ivCBYH/multi-carousel-single-slide-bootstrap-4
// non-related styling:
body{
background: #333;
color: #ddd;
}
@ci: carousel-item;
@media (min-width: 768px) {
.multi-item-carousel {
.carousel-inner {
.@{ci} {
// NEW to v4.3.1: all margin-right properties come with -100% as default
// causing all hidden items to be out of the screen
margin-right: inherit;
&.active {
+ .@{ci},
+ .@{ci} + .@{ci} {
display: block; // three visible items
}
// prevents opposite direction "animation"
&:not(.@{ci}-right):not(.@{ci}-left),
&:not(.@{ci}-right):not(.@{ci}-left) + .@{ci},
&:not(.@{ci}-right):not(.@{ci}-left) + .@{ci} + .@{ci} {
transition: none;
}
// allows new item to be visible in order to "slide in" into place
+ .@{ci} + .@{ci} + .@{ci} {
position: absolute;
top: 0;
right: -(percentage(1/3));
z-index: -1;
display: block;
visibility: visible;
}
} // .active
&-next,
&-prev {
position: relative;
transform: translate3d(0, 0, 0);
}
} // .carousel-item
// farthest right hidden item must be also positioned for animations
.@{ci}-prev.@{ci}-right {
position: absolute;
top: 0;
left: 0;
z-index: -1;
display: block;
visibility: visible;
}
} // .carousel-inner
// left or forward direction
.active.@{ci}-left + .@{ci}-next.@{ci}-left,
.@{ci}-next.@{ci}-left + .@{ci},
.@{ci}-next.@{ci}-left + .@{ci} + .@{ci},
.@{ci}-next.@{ci}-left + .@{ci} + .@{ci} + .@{ci} {
position: relative;
transform: translate3d(-100%, 0, 0);
visibility: visible;
}
// right or previous direction
.active.@{ci}-right + .@{ci}-prev.@{ci}-right,
.@{ci}-prev.@{ci}-right + .@{ci},
.@{ci}-prev.@{ci}-right + .@{ci} + .@{ci},
.@{ci}-prev.@{ci}-right + .@{ci} + .@{ci} + .@{ci} {
position: relative;
transform: translate3d(100%, 0, 0);
display: block;
visibility: visible;
}
} // multi-item-carousel
}
View Compiled
// Developed at agap2
// Based on:
// http://www.codeply.com/go/s3I9ivCBYH/multi-carousel-single-slide-bootstrap-4
$('.multi-item-carousel').on('slide.bs.carousel', function (e) {
let $e = $(e.relatedTarget),
itemsPerSlide = 3,
totalItems = $('.carousel-item', this).length,
$itemsContainer = $('.carousel-inner', this),
it = itemsPerSlide - (totalItems - $e.index());
if (it > 0) {
for (var i = 0; i < it; i++) {
$('.carousel-item', this).eq(e.direction == "left" ? i : 0).
// append slides to the end/beginning
appendTo($itemsContainer);
}
}
});