Incomplete Slides Bootstrap 5 Carousels Fix

Incomplete Slides Bootstrap 5 Carousels Fix

If you're building a Drupal 10 or 11 website and using a Bootstrap 5 carousel to showcase taxonomy terms, images, or custom content through Views, you may have run into this annoying UX glitch:

The last slide doesn’t fill up — leaving one lonely image hanging out by itself.

Let’s fix that.

The Problem: Incomplete Carousel Slides Using Bootstrap Carousel with Drupal Views

By default, Bootstrap Carousel rotates entire .carousel-item elements. If your Drupal View is set to show 3 items per slide, but the total number of items isn’t divisible by 3, the last slide will look broken or awkward:

  • Uneven layout
  • Empty space on the right
  • Frustrated designer energy

This happens because Bootstrap doesn't "wrap around" items within a slide, only whole slides.

The Goal

We want to automatically fill the last slide by cloning items from the start of the carousel, so every slide looks full and polished, even if the total item count isn’t perfectly divisible.

And we want it to work with any number of items per slide, as defined in Drupal Views.

The Solution: JavaScript Carousel Patch

Here’s the JavaScript snippet that auto-detects how many items belong on a slide, and clones items into the final one to make it complete:

document.addEventListener("DOMContentLoaded", function () {
  document.querySelectorAll('.carousel-inner').forEach(function (carouselInner) {
    const items = carouselInner.querySelectorAll('.carousel-item');
    if (items.length === 0) return;

    const firstItem = items[0];
    const itemsPerSlide = firstItem.querySelectorAll('.col-md-3').length;

    items.forEach((item, index) => {
      const currentCols = item.querySelectorAll('.col-md-3');
      const colsNeeded = itemsPerSlide - currentCols.length;

      if (colsNeeded > 0) {
        let cloneIndex = 0;

        while (item.querySelectorAll('.col-md-3').length < itemsPerSlide) {
          const sourceItem = items[cloneIndex];
          const sourceCols = sourceItem.querySelectorAll('.col-md-3');

          sourceCols.forEach((col) => {
            if (item.querySelectorAll('.col-md-3').length < itemsPerSlide) {
              const clone = col.cloneNode(true);
              item.querySelector('.row').appendChild(clone);
            }
          });

          cloneIndex++;
          if (cloneIndex >= items.length) break;
        }
      }
    });
  });
});

 

Features

  • No need to hardcode the number of columns
  • Works with dynamic Views settings (e.g. 2, 3, or 4 items per slide)
  • Pure JS — no dependencies required
  • Works seamlessly with Bootstrap 5 and Drupal's views_bootstrap module

How to Add the Fix in Drupal

  1. Save the JS code into your theme's /js/ directory — for example:
    themes/custom/yourtheme/js/carousel-wrap-fix.js
  2. Declare the library in your yourtheme.libraries.yml:

    
    carousel-enhancer:
     js:
        js/carousel-wrap-fix.js: {}
     dependencies:
        - core/drupal
  3.   Attach the library to your view’s Twig template:
    Add this line in the carousel template (usually views-view-unformatted--carousel.html.twig or similar):  

    {{ attach_library('yourtheme/carousel-enhancer') }}
     
  4. Clear Drupal’s cache and reload your page:

    drush cr

Final Result

Your Drupal Bootstrap carousel will now:

  • Always show fully populated slides
  • Look cleaner and more professional
  • Deliver a smooth, looped UX — even with uneven item counts
  • No more “one lonely card” syndrome.

Combine With Custom CSS

Add styling for your carousel content, center titles, position icons, remove padding, etc. — to fully polish the look. Here’s a quick example:

.carousel-item .col {
 padding: 0;
}
.carousel-item h3 {
 text-align: center;
 color: white;
}
.term-icon {
 position: absolute;
 bottom: 5px;
 right: 5px;
}

You will now have a functioning Bootstrap 5 Carousel that wraps so you don't have to!

Let us know about your experience in the comments!

Category