Search code examples
jquerybootstrap-4media-queriescarouselbootstrap-carousel

Fixing a Bootstrap 4 multiple item carousel on XL screen


(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!


Solution

  • 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/[email protected]/dist/umd/popper.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>