1

(This is definitely not a duplicate).

I implemented a Bootstrap 4 carousel that displays multiple items. It has to cover these specific requirements for different screen sizes:

  • 0 - md screens (just before md starts): carousel with 2 visible items
  • md - lg screens (just before lg starts): carousel with 3 visible items
  • lg - xl screens (just before xl starts): carousel with 4 visible items
  • xl screens and beyond: carousel with 6 visible items

It works very well except on the xl media query. I've been trying to fix this issue for hours without success:

  1. if the screen's width is 1200px or more (xl), the carousel is only displaying 4 or 5 items instead of 6, therefore causing a strange flickering behavior when cycling through the items.

sm screen 675px. This works fine.

sm screen 576px

md screen 768px. This works fine.

md screen 768px

lg screen 992pxx. This works fine.

lg screen 992px

xl screen 1200px As you can see, only 4 items are being displayed (sometimes 5 when starting the example). This screen size should be displaying 6 items.

xl screen 1200px

  1. if you press Prev and then Next, there will be a small but unidentified delay for the new item coming in from the right of the carousel.

The first bug must be fixed, but it would be nice to also fix the 2nd one.

Instead of pasting the code here, I've added a live example in the link below:

https://jsitor.com/SQENGSYDz

Thanks for your help!

Andres SK
  • 10,779
  • 25
  • 90
  • 152
  • I think you must use @Zim carousel https://stackoverflow.com/a/20008623/8798220 – Nisharg Shah Apr 17 '20 at 23:35
  • Thanks, but changing carousel plugins is not an option right now. – Andres SK Apr 17 '20 at 23:39
  • what you mean by plugins? – Nisharg Shah Apr 17 '20 at 23:49
  • i thought it was a plugin, just checked it. The issue is that the solution posted in the other thread doesn't cover the requirements of changing the item count depending on the screen size. This solution covers this, except with the XL screen size where the bug can be found. – Andres SK Apr 17 '20 at 23:53

2 Answers2

1

Here is your solution, based on this https://stackoverflow.com/a/20008623/8798220

If you found a glitch on slide, you can use How to add gap between images in carousel slider or remove glitch when slide concept ( my own question )

$('#recipeCarousel').carousel({
    interval: 250000
})

$('.carousel .carousel-item').each(function(){
    var minPerSlide = 4;
    var next = $(this).next();
    if (!next.length) {
        next = $(this).siblings(':first');
    }
    next.children(':first-child').clone().appendTo($(this));

    for (var i=0;i<minPerSlide;i++) {
        next=next.next();
        if (!next.length) {
            next = $(this).siblings(':first');
        }

        next.children(':first-child').clone().appendTo($(this));
    }
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">

<style>
.carousel-inner .carousel-item.active,
.carousel-inner .carousel-item-next,
.carousel-inner .carousel-item-prev {
    display: flex;
}

.carousel-inner .carousel-item-right.active,
.carousel-inner .carousel-item-next {
    transform: translateX(50%);
}

.carousel-inner .carousel-item-left.active, 
.carousel-inner .carousel-item-prev {
    transform: translateX(-50%);
}

@media (min-width: 768px) and (max-width: 992px) {
    .carousel-inner .carousel-item-right.active,
    .carousel-inner .carousel-item-next {
        transform: translateX(33.33%);
    }

    .carousel-inner .carousel-item-left.active, 
    .carousel-inner .carousel-item-prev {
        transform: translateX(-33.33%);
    }
}

@media (min-width: 992px) and (max-width: 1200px) {
    .carousel-inner .carousel-item-right.active,
    .carousel-inner .carousel-item-next {
        transform: translateX(25%);
    }

    .carousel-inner .carousel-item-left.active, 
    .carousel-inner .carousel-item-prev {
        transform: translateX(-25%);
    }
}

@media (min-width: 1200px) {
    .carousel-inner .carousel-item-right.active,
    .carousel-inner .carousel-item-next {
        transform: translateX(16%);
    }

    .carousel-inner .carousel-item-left.active, 
    .carousel-inner .carousel-item-prev {
        transform: translateX(-16%);
    }
}

.carousel-inner .carousel-item-right,
.carousel-inner .carousel-item-left{ 
    transform: translateX(0);
}
</style>

<div class="container text-center my-3">
  <h2 class="font-weight-light">Bootstrap 4 - Multi Item Carousel</h2>
  <div class="row mx-auto my-auto">
      <div id="recipeCarousel" class="carousel slide w-100" data-ride="carousel">
          <div class="carousel-inner w-100" role="listbox">
              <div class="carousel-item active">
                  <img class="img-fluid col-6 col-md-4 col-lg-3 col-xl-2" src="http://placehold.it/380?text=1">
              </div>
              <div class="carousel-item">
                  <img class="img-fluid col-6 col-md-4 col-lg-3 col-xl-2" src="http://placehold.it/380?text=2">
              </div>
              <div class="carousel-item">
                  <img class="img-fluid col-6 col-md-4 col-lg-3 col-xl-2" src="http://placehold.it/380?text=3">
              </div>
              <div class="carousel-item">
                  <img class="img-fluid col-6 col-md-4 col-lg-3 col-xl-2" src="http://placehold.it/380?text=4">
              </div>
              <div class="carousel-item">
                  <img class="img-fluid col-6 col-md-4 col-lg-3 col-xl-2" src="http://placehold.it/380?text=5">
              </div>
              <div class="carousel-item">
                  <img class="img-fluid col-6 col-md-4 col-lg-3 col-xl-2" src="http://placehold.it/380?text=6">
              </div>
          </div>
          <a class="carousel-control-prev w-auto" href="#recipeCarousel" role="button" data-slide="prev">
              <span class="carousel-control-prev-icon bg-dark border border-dark rounded-circle" aria-hidden="true"></span>
              <span class="sr-only">Previous</span>
          </a>
          <a class="carousel-control-next w-auto" href="#recipeCarousel" role="button" data-slide="next">
              <span class="carousel-control-next-icon bg-dark border border-dark rounded-circle" aria-hidden="true"></span>
              <span class="sr-only">Next</span>
          </a>
      </div>
  </div>
  <h5 class="mt-2">Advances one slide at a time</h5>
</div>

<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
Nisharg Shah
  • 16,638
  • 10
  • 62
  • 73
  • upvote to comment!! I tried to solve your problem but no response from your side? why? – Nisharg Shah Apr 19 '20 at 22:11
  • Hi @Nisharg I upvoted your answer because it works, but I can't mark it as the solution because the the fix must be made directly on the live example code by modifying the existing css. I added a bounty with 50 points. – Andres SK Apr 20 '20 at 16:51
  • I ended using this solution, it worked better than the other one in all cases. The bounty has been rewarded to your account. Thanks! – Andres SK Apr 22 '20 at 15:31
1

I hope you like my second answer.

Explanation

the screen's width is 1200px or more (xl), the carousel is only displaying 4 or 5 items instead of 6, therefore causing a strange flickering behavior when cycling through the items.

Every 4th element cant get CSS of transition, so I added the CSS of it in @media query (min-width: 1200px) and now it display 6 items.

As you can see, only 4 items are being displayed (sometimes 5 when starting the example). This screen size should be displaying 6 items.

Because you added var items_per_slide = Math.round(total_items / 2); in your code and always total_items are 7 so it will give you 4 answer, so this will only applicable for 4 items in one row.

so I statically added 6 in your code and your problem is solved.

if you press Prev and then Next, there will be a small but unidentified delay for the new item coming in from the right of the carousel.

It's because of you hard-coded 33.333333333333333% and -16.666666666666667% in your code and that creates some delay.

https://codepen.io/nisharg/pen/YzyGvQN?editors=0111

Nisharg Shah
  • 16,638
  • 10
  • 62
  • 73
  • Hi! This solution almost works, except when pressing the previous button when having the 6 items visible (1200px and more). If I press previous, the last item is being visually transfered to the left instead of achieving the desired carousel effect. I tried finding the issue in your code without success. If you solve that, the bounty is definitely yours! – Andres SK Apr 22 '20 at 07:41
  • I tried but I can't fix it, let me try again, Hopefully it will fix – Nisharg Shah Apr 22 '20 at 10:27