Bootstrap 4 Carousel with Multiple Items: How To Create It?

Updated on: Feb 21 2023 by Anli

Bootstrap 4 Carousel with Multiple Items: How To Create It?

A few days ago I created these Bootstrap 4 Carousel templates and then I wrote a tutorial about different ways to disable the autoplay feature.

Today we’ll continue with another tutorial, this time about how to create a responsive Bootstrap 4 Carousel with Multiple Items.

We’ll do this by using some CSS media queries and, as usual, some JavaScript (jQuery) code. Let’s see!

1. Introduction

For this tutorial we’ll use one of the templates I mentioned above, which I’ve created using the Bootstrap carousel component. Also we’ll use Bootstrap version 4.2.1.

Here is an image preview of the final result:

Bootstrap 4 Carousel with Multiple Items

And here is a LIVE DEMO.

Before writing this tutorial I didn’t know how to create this type of carousel or slideshow. So with a few Google searches I found this discussion on stackoverflow.

There I found this code, which was based on this, which was made by this company (thank you 😉 ).

I took that code, customized it a bit to match the style of my template and, after some trial and error, I managed to create the carousel just as I wanted it and as we’re seeing in this guide.

Ok, after this introduction, now let’s continue with the HTML code.

2. The HTML

The HTML code which you can find in the “index.html” file, is very simple as it’s similar to a “normal” Bootstrap carousel.

The difference is that we use different columns for each image and different column sizes for each screen size (smartphones, tablets, desktops) to make it responsive. Read the Bootstrap grid documentation here to learn more or just to refresh your memory.

Here is the HTML code:

<!-- Top content -->
<div class="top-content">
    <div class="container-fluid">
        <div id="carousel-example" class="carousel slide" data-ride="carousel">
            <div class="carousel-inner row w-100 mx-auto" role="listbox">
                <div class="carousel-item col-12 col-sm-6 col-md-4 col-lg-3 active">
                    <img src="assets/img/backgrounds/1.jpg" class="img-fluid mx-auto d-block" alt="img1">
                </div>
                <div class="carousel-item col-12 col-sm-6 col-md-4 col-lg-3">
                    <img src="assets/img/backgrounds/2.jpg" class="img-fluid mx-auto d-block" alt="img2">
                </div>
                <div class="carousel-item col-12 col-sm-6 col-md-4 col-lg-3">
                    <img src="assets/img/backgrounds/3.jpg" class="img-fluid mx-auto d-block" alt="img3">
                </div>
                <div class="carousel-item col-12 col-sm-6 col-md-4 col-lg-3">
                    <img src="assets/img/backgrounds/4.jpg" class="img-fluid mx-auto d-block" alt="img4">
                </div>
                <div class="carousel-item col-12 col-sm-6 col-md-4 col-lg-3">
                    <img src="assets/img/backgrounds/5.jpg" class="img-fluid mx-auto d-block" alt="img5">
                </div>
                <div class="carousel-item col-12 col-sm-6 col-md-4 col-lg-3">
                    <img src="assets/img/backgrounds/6.jpg" class="img-fluid mx-auto d-block" alt="img6">
                </div>
                <div class="carousel-item col-12 col-sm-6 col-md-4 col-lg-3">
                    <img src="assets/img/backgrounds/7.jpg" class="img-fluid mx-auto d-block" alt="img7">
                </div>
                <div class="carousel-item col-12 col-sm-6 col-md-4 col-lg-3">
                    <img src="assets/img/backgrounds/8.jpg" class="img-fluid mx-auto d-block" alt="img8">
                </div>
            </div>
            <a class="carousel-control-prev" href="#carousel-example" 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="#carousel-example" role="button" data-slide="next">
                <span class="carousel-control-next-icon" aria-hidden="true"></span>
                <span class="sr-only">Next</span>
            </a>
        </div>
    </div>
</div>

3. The CSS

I have divided the CSS code in 3 files for simplicity (“style.css”, “media-queries.css”, “carousel.css”) but you can merge them together in a production website to reduce HTTP requests and improve load time. You can find them in the folder “assets/css”.

As the name suggests, the code that handles the carousel behaviour is in “carousel.css”. As I said above, I found it with a few Google searches and modified it for my template.

The code in the other two files (“style.css” and “media-queries.css”) is for styling other parts of the template, not the carousel. I’ll not show it here, to keep the tutorial short.

We use some Media Queries to display the various slides in different screen sizes.

Here is the CSS code:

/*
    code by Iatek LLC 2018 - CC 2.0 License - Attribution required
    code customized by Azmind.com
*/
@media (min-width: 768px) and (max-width: 991px) {
    /* Show 4th slide on md if col-md-4*/
    .carousel-inner .active.col-md-4.carousel-item + .carousel-item + .carousel-item + .carousel-item {
        position: absolute;
        top: 0;
        right: -33.3333%;  /*change this with javascript in the future*/
        z-index: -1;
        display: block;
        visibility: visible;
    }
}
@media (min-width: 576px) and (max-width: 768px) {
    /* Show 3rd slide on sm if col-sm-6*/
    .carousel-inner .active.col-sm-6.carousel-item + .carousel-item + .carousel-item {
        position: absolute;
        top: 0;
        right: -50%;  /*change this with javascript in the future*/
        z-index: -1;
        display: block;
        visibility: visible;
    }
}
@media (min-width: 576px) {
    .carousel-item {
        margin-right: 0;
    }
    /* show 2 items */
    .carousel-inner .active + .carousel-item {
        display: block;
    }
    .carousel-inner .carousel-item.active:not(.carousel-item-right):not(.carousel-item-left),
    .carousel-inner .carousel-item.active:not(.carousel-item-right):not(.carousel-item-left) + .carousel-item {
        transition: none;
    }
    .carousel-inner .carousel-item-next {
        position: relative;
        transform: translate3d(0, 0, 0);
    }
    /* left or forward direction */
    .active.carousel-item-left + .carousel-item-next.carousel-item-left,
    .carousel-item-next.carousel-item-left + .carousel-item,
    .carousel-item-next.carousel-item-left + .carousel-item + .carousel-item {
        position: relative;
        transform: translate3d(-100%, 0, 0);
        visibility: visible;
    }
    /* farthest right hidden item must be also positioned for animations */
    .carousel-inner .carousel-item-prev.carousel-item-right {
        position: absolute;
        top: 0;
        left: 0;
        z-index: -1;
        display: block;
        visibility: visible;
    }
    /* right or prev direction */
    .active.carousel-item-right + .carousel-item-prev.carousel-item-right,
    .carousel-item-prev.carousel-item-right + .carousel-item,
    .carousel-item-prev.carousel-item-right + .carousel-item + .carousel-item {
        position: relative;
        transform: translate3d(100%, 0, 0);
        visibility: visible;
        display: block;
        visibility: visible;
    }
}
/* MD */
@media (min-width: 768px) {
    /* show 3rd of 3 item slide */
    .carousel-inner .active + .carousel-item + .carousel-item {
        display: block;
    }
    .carousel-inner .carousel-item.active:not(.carousel-item-right):not(.carousel-item-left) + .carousel-item + .carousel-item {
        transition: none;
    }
    .carousel-inner .carousel-item-next {
        position: relative;
        transform: translate3d(0, 0, 0);
    }
    /* left or forward direction */
    .carousel-item-next.carousel-item-left + .carousel-item + .carousel-item + .carousel-item {
        position: relative;
        transform: translate3d(-100%, 0, 0);
        visibility: visible;
    }
    /* right or prev direction */
    .carousel-item-prev.carousel-item-right + .carousel-item + .carousel-item + .carousel-item {
        position: relative;
        transform: translate3d(100%, 0, 0);
        visibility: visible;
        display: block;
        visibility: visible;
    }
}
/* LG */
@media (min-width: 991px) {
    /* show 4th item */
    .carousel-inner .active + .carousel-item + .carousel-item + .carousel-item {
        display: block;
    }
    .carousel-inner .carousel-item.active:not(.carousel-item-right):not(.carousel-item-left) + .carousel-item + .carousel-item + .carousel-item {
        transition: none;
    }
    /* Show 5th slide on lg if col-lg-3 */
    .carousel-inner .active.col-lg-3.carousel-item + .carousel-item + .carousel-item + .carousel-item + .carousel-item {
        position: absolute;
        top: 0;
        right: -25%;  /*change this with javascript in the future*/
        z-index: -1;
        display: block;
        visibility: visible;
    }
    /* left or forward direction */
    .carousel-item-next.carousel-item-left + .carousel-item + .carousel-item + .carousel-item + .carousel-item {
        position: relative;
        transform: translate3d(-100%, 0, 0);
        visibility: visible;
    }
    /* right or prev direction //t - previous slide direction last item animation fix */
    .carousel-item-prev.carousel-item-right + .carousel-item + .carousel-item + .carousel-item + .carousel-item {
        position: relative;
        transform: translate3d(100%, 0, 0);
        visibility: visible;
        display: block;
        visibility: visible;
    }
}

4. The JavaScript

Now with the JavaScript (jQuery) code that you can see below and that I’ve added in the file “scripts.js” (assets/js), we use the event “slide.bs.carousel” to append the slides in the right position of the carousel immediately when the carousel moves to the left or right.

Here you can see the available Bootstrap carousel’s events.

And here is the JavaScript code:

/*
    Carousel
*/
$('#carousel-example').on('slide.bs.carousel', function (e) {
    /*
        CC 2.0 License Iatek LLC 2018 - Attribution required
    */
    var $e = $(e.relatedTarget);
    var idx = $e.index();
    var itemsPerSlide = 5;
    var totalItems = $('.carousel-item').length;

    if (idx >= totalItems-(itemsPerSlide-1)) {
        var it = itemsPerSlide - (totalItems - idx);
        for (var i=0; i<it; i++) {
            // append slides to end
            if (e.direction=="left") {
                $('.carousel-item').eq(i).appendTo('.carousel-inner');
            }
            else {
                $('.carousel-item').eq(0).appendTo('.carousel-inner');
            }
        }
    }
});

5. Demo, Download and License

VIEW DEMO

DOWNLOAD FREE on Gumroad: Get the Bootstrap Carousel with Multiple Items

LICENSE:

You can use these templates in personal and commercial projects (if not otherwise specified in the single files), but you can’t sell or distribute them directly, “as is”. If you plan to use them, a link to this page or any form of spreading the word will be much appreciated.

6. Conclusion

That’s it! I hope you learned something new with this tutorial that you can use in your projects.

The carousel we created shows 4 slides at a time in large (desktop) screens, but you can play and experiment with the code if you want to show a different number of slides.

If you have any question or suggestion, let me know in the comments below.

Filed under: Bootstrap, Tutorials

39 Comments So Far

  1. Lrrr says:

    Carousel not working for number of items same or less then itemsPerSlide variable.

  2. Sebastiaan van Dijk says:

    Hi, this finally is a version that just works in all versions of Bootstrap 4. I’ve adapted it to use cards instead of just images, which gives a nice twist. What gets me though is that I ony need to show three items instead of four on large screens, but I cannot for the life of me figure out what the magic combination is to adapt your code to cater for that. Whichever way I tweak this I get that the next or previous slide is only loaded when the user clicks the previous/next buttons. In the above example it seems like the next/previous item is preloaded or something. Can you give a hin as to how to tweak the code to only show three instead of four to begin with? I.e. not the lg-3 option, but just start with md-4. The responsiveness shouldn’t change as the way it works now it is great.

  3. Zuhaib sarwat says:

    Last item doesnt loop back to first item.slide takes 3 more transition for the first item to show..

    • Narpat Singh Rawat says:

      Hey I have also faced the same issue but when i includes the jquery files above the local js file the issue has been resolved. hope this will help you

  4. Zuhaib sarwat says:

    carousel not showing first element after the last element instead takes 3 more transition for the first one to show. help on this anyone???

  5. Ihsan Fajari says:

    Works well for me, thanks for sharing this code!

  6. sam says:

    How can I change the transition and show 8 items by slides?

  7. abdollah says:

    one carousel is work bu when i use two slider in one page dosent work

    • John says:

      Hi, did you find solution for this issue? Use two sliders in same page?

      • Janeagainst says:

        Hello, I found the solution for this problem..:
        Whenever carousel.item is referred, it interferes with other carousels on the page, so my solution was to add id=”countme” in each item so that it wouldnt interfere with carousels that dont have this id
        var $e = $(e.relatedTarget);
        var idx = $e.index();
        var itemsPerSlide = 5;
        var totalItems = $(‘#countme’).length
        if (idx >= totalItems-(itemsPerSlide-1)) {
        var it = itemsPerSlide – (totalItems – idx);
        for (var i=0; i<it; i++) {
        // append slides to end
        if (e.direction=="left") {
        $('#countme').eq(i).appendTo('#prodinner'); /*not sure if prodinner is needed */
        }
        else {
        $('#countme').eq(0).appendTo('#prodinner');
        }
        }
        }

      • Sayed says:

        I am not able to call same slider twice on same page.

  8. Apple says:

    Hello! carousel not showing first element after the last element instead takes 3 more transition for the first one to show. help on this anyone??? how to fix?

    • Seyi says:

      Hi, Did you find a solution to this issue? The loop did not work well for me also

    • Noel says:

      $(document).ready(function() { = totalItems – (itemsPerSlide – 1)) {
      var it = itemsPerSlide – (totalItems – idx);
      for (var i = 0; i < it; i++) {
      // append slides to end
      if (e.direction == "left") {
      $(".carousel-item")
      .eq(i)
      .appendTo(".carousel-inner");
      } else {
      $(".carousel-item")
      .eq(0)
      .appendTo($(this).find(".carousel-inner"));
      }
      }
      }
      });
      }); <——add here

  9. mona says:

    Hi, thank you for ur great work, i’ve a question..
    i need to customize the design and add 6 items in row, i added the class “col-lg-2” but it’s not working.
    thank u in advanced 🙂 .

  10. Alan says:

    It looks like the index (idx) in the JavaScript is always 4, making the loop unnecessary.

    if (idx >= totalItems-(itemsPerSlide-1)) {

    $(‘.carousel-item’).eq(0).appendTo(‘.carousel-inner’);

    }

    • Seyi says:

      Hi, Can you please share your solution to the loop issue? After the last item, it takes 3 empty slides before the first item shows.

  11. Gabe says:

    Thank you for the great tutorial! It works exactly the way I want it to. This is the fifth tutorial I tried for a multi item carousel that advances one item at a time, works in Bootstrap 4, and is responsive without getting wonky.

  12. rab says:

    I have an RTL web site. I can’t seem to work it out. It only shows one slide at a time and not 4 at same time(ltr)?

  13. Oluwaseyi Olarotimi says:

    The slide does not automatically loop back to the first image when I used this code. It shows 3 empty spaces after the last image before eventually showing the first image. Can anybody please share their solution to this issue.

  14. Seyi says:

    The slide does not automatically loop back to the first image when I used this code. It shows 3 empty spaces after the last image before eventually showing the first image. Can anybody please share their solution to this issue?

    • susie says:

      Use below

      $(document).ready(function () {
      $(‘#carousel-example’).on(‘slide.bs.carousel’, function (e) {
      /*
      CC 2.0 License Iatek LLC 2018 – Attribution required
      */
      var $e = $(e.relatedTarget);
      var idx = $e.index();
      var itemsPerSlide = 4;
      var totalItems = $(‘.carousel-item’).length;

      if (idx >= totalItems-(itemsPerSlide-1)) {
      var it = itemsPerSlide – (totalItems – idx);
      for (var i=0; i<it; i++) {
      // append slides to end
      if (e.direction=="left") {
      $('.carousel-item').eq(i).appendTo('.carousel-inner');
      }
      else {
      $(".carousel-item").eq(0).appendTo(".carousel-inner");
      }
      }
      }
      });
      });

  15. Akil says:

    Hi, When I try to implement Carousel sliders two times, one below another in single page, I’m facing issues in slider actions. we changed the ID and replicate the codes in both “index.html” and “script.js” file.
    Please help to solve this issue.
    Thanks

  16. Kevin says:

    The carousel won’t automatically loop back to first element after the last one is shown, it keeps looping until the entire carousel is blank and switches back to first. Considering learning more JS because this wild goose chase is ridiculous.

  17. roro says:

    Hi, thanks for the tutorial
    it works fine when it’s uncompressed but why is there a delay to display the last picture when it scrolls?
    thanks

  18. Hamza Belabed says:

    Any idea how to integrate it with Angular 7 ? cuz we can’t use the “on” event slide.bs.carousel

  19. King Pista says:

    If I do not use exactly 8 items, as in the example, it will not work properly – whatever value I give to the itemsPerSlide variable.

  20. Rafael says:

    Hello, i’m rafael from Argentine.
    I find the solution.

    $(‘#carousel-example’).on(‘slide.bs.carousel’, function (e) {

    var e = $(e.relatedTarget);
    var idx = e.index();

    var itemsPerSlide = 4;
    var totalItems = $(‘.carousel-item’).length;
    console.log(“totalitems:”+totalItems);
    console.log(“e:”+e);
    console.log(“idx:”+idx);

    if (idx >= totalItems-(itemsPerSlide-1)) {
    var it = itemsPerSlide – (totalItems – idx);
    console.log(“it:”+it);
    for (var i=0; i<it; i++) {
    // append slides to end

    if (e.direction==="left") {
    $('.carousel-item').eq(i).appendTo('.carousel-inner');
    }
    else {
    $('.carousel-item').eq(0).appendTo('.carousel-item');
    }
    }
    }
    });

  21. Steve says:

    Hey, i have a problem when i Use 2 different Sliders (one Original Bootstrap Slider and this one). the Original Slider uses the bootstrap.css so when i add the carousel.css is my Original Bootstrap Slider broken.
    I try to give all carousel-inner & carousel-item classes a new class name in the css an html like carousel-inner2 and carousel-item2
    That works, but then doesn’t work the slide animations anymore. Have you any solutions for this case? thx

  22. Ellen says:

    For others’ future reference, it’s the CSS you need to change to add more items. Took me forever to figure this out. I managed to get 6 columns (still working on getting the transitions to work properly). It doesn’t seem like the itemsPerSlide does anything? Idk. Also note that there are references to the columns in the css, so if you change your column sizes, you will need to change those in the css too.

  23. mike says:

    hello,

    nice code.

    in large version need to show 6 items…

    i tried to change de value in js but it doens’t work

  24. Fárr Vince says:

    Hello.

    Thank you for your slider. It works fine.

    I have a question: Is it possible to add indicator like the normal Carousel?

    I tried with the same code, but after the 4th active indicator, does not continue to change the bullets.

    If you have any solution, I will appreciate it. 😊

    Thank you very much!
    With respect,
    Vince Fárr

    P.S.
    Please if you answer, send me on e-mail because I don’t check every day this page.

  25. Rubén says:

    FIX ABOUT THE JQUERY:

    Ok guys, just change this and will work:

    var itemsPerSlide = 5;
    var totalItems = $(‘.carousel-item’).length;

    Change it for:
    var totalItems = $(‘.carousel-item’).length;
    var itemsPerSlide = totalItems – 3;

    By the way, if you are using more than one slider in the same page, just write ‘#carousel-example .carousel-item’ instead of ‘.carousel-item’

  26. Jospin says:

    Hello thanks for this great code. Please i am trying to center the active item. I am displaying three at once and want the selected one to be centered. Any help? Thanks.

  27. Mike says:

    Hi there, I’ve managed to get this working. Except I have a problem with the slides transitioning from off screen to on screen not appearing until after the slide animation is complete. Any idea why this might be happening someone?

  28. Timothy Michael Gangl says:

    I am trying to use 4 carousels on the same page showing 4 images that are also clickable. First of I am having trouble getting the first image to loop around after the last one. Also what was changed to let multiple carousels work independently on the same page. Lastly with it clicking to the next on e how can you make an image clickable?

Leave a Reply to abdollah

To learn how we use your data when you comment, read our Privacy Policy here.