How to Convert Bootstrap Carousel Indicators Into Animated Progress Bars
In this tutorial, we’ll work with another exciting Bootstrap extension. Specifically, we’ll build a Bootstrap carousel component and customize its indicators to look like animated progress bars. In that way, we’ll have a clear view of when the next slide is about to load.
Our Bootstrap Carousel Extension
Here’s what we’ll be creating:
1. Create a Bootstrap Carousel With Indicators
Assuming that we’ve installed the required Bootstrap files, we’ll first construct an image carousel (images from Unsplash) with indicators, by taking advantage of the basic code for the carousel component that the framework provides us.
Here’s the necessary code:
1 |
<div id="carouselExampleIndicators" class="carousel slide" data-bs-ride="carousel" data-bs-pause="false"> |
2 |
<div class="carousel-indicators"> |
3 |
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"> |
4 |
<span></span>
|
5 |
</button>
|
6 |
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="1" aria-label="Slide 2"> |
7 |
<span></span>
|
8 |
</button>
|
9 |
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="2" aria-label="Slide 3"> |
10 |
<span></span>
|
11 |
</button>
|
12 |
</div>
|
13 |
<div class="carousel-inner"> |
14 |
<div class="carousel-item active"> |
15 |
<img src="bs-carousel1.jpg" class="d-block w-100" alt="..."> |
16 |
</div>
|
17 |
<div class="carousel-item"> |
18 |
<img src="bs-carousel2.jpg" class="d-block w-100" alt="..."> |
19 |
</div>
|
20 |
<div class="carousel-item"> |
21 |
<img src="bs-carousel3.jpg" class="d-block w-100" alt="..."> |
22 |
</div>
|
23 |
</div>
|
24 |
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide="prev"> |
25 |
<span class="carousel-control-prev-icon" aria-hidden="true"></span> |
26 |
<span class="visually-hidden">Previous</span> |
27 |
</button>
|
28 |
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide="next"> |
29 |
<span class="carousel-control-next-icon" aria-hidden="true"></span> |
30 |
<span class="visually-hidden">Next</span> |
31 |
</button>
|
32 |
</div>
|
Pay attention to two things:
- We add the
data-bs-pause="false"
attribute to prevent pausing the carousel when we hover over it. - We add an empty
span
element to each carousel indicator. That will behave as our progress bar.
2. Customize the Bootstrap Indicators
As a next step, we’ll customize the default indicators styling. We’ll make them bigger and absolutely position their span
on top of it. Initially, the span
s will have zero-width. That width will increase gradually as soon as the corresponding slide becomes active.



Here are the associated styles:
1 |
.carousel-indicators [data-bs-target] { |
2 |
position: relative; |
3 |
width: 60px; |
4 |
height: 6px; |
5 |
border: none; |
6 |
border-radius: 24px; |
7 |
}
|
8 |
|
9 |
.carousel-indicators [data-bs-target] span { |
10 |
content: ’’; |
11 |
position: absolute; |
12 |
top: 0; |
13 |
left: 0; |
14 |
width: 0; |
15 |
height: 100%; |
16 |
background: #7952b3; |
17 |
border-radius: inherit; |
18 |
}
|
3. Create a Progress Element for Each Slide
When the page loads or a slide changes, the fillCarouselIndicator()
function will fire.
This function will receive as a parameter the active slide. Initially, we’ll consider the first slide to be the active one.
Inside it, we’ll do the following things:
- Run a function every 50ms whose job will be to gradually animate the
span
width of the active indicator up to 100%. - Initially, set the width of all
span
s to zero and cancel the execution of the scheduled call (if any). We do this as a precaution in case we decide to change a slide earlier than Bootstrap’s default autoplay behavior (every 5000ms).

With all the above in mind, here’s the associated code:
1 |
...
|
2 |
|
3 |
function fillCarouselIndicator(index) { |
4 |
let i = 0; |
5 |
// 2
|
6 |
for (const carouselIndicator of carouselIndicators) { |
7 |
carouselIndicator.style.width = 0; |
8 |
}
|
9 |
clearInterval(intervalID); |
10 |
|
11 |
// 1
|
12 |
intervalID = setInterval(function () { |
13 |
i++; |
14 |
myCarousel.querySelector(".carousel-indicators .active span").style.width = |
15 |
i + "%"; |
16 |
}, 50); |
17 |
}
|
setInterval()
method should run every 50ms. Normally, its last call is when the value of the i
variable is set to 100 (100 * 50 = 5000). If, for some reason, you want to change the predefined time needed for cycling between slides, remember, also, to modify the given interval time accordingly. For example, if you set the carousel’s interval time to 6000, you have to give 60 as the second parameter of our interval method.Accuracy?
If you have ever worked with JavaScript timers (setTimeout()
, setInterval()
), you might have seen that they aren’t always accurate. Besides, they can behave differently across various browsers/devices.
In my testing, our example worked fine in browsers like Chrome and Edge, but on Firefox, the next slide was revealing while the active indicator had a width of around 80%.

So, let’s perform a simple fix to ensure browser compatibility. More specifically, we’ll add three things:
- First, we’ll get a reference for our carousel. That will give us the ability to use its API methods.
- Then, each time a slide changes, we’ll pause the carousel.
- Finally, we’ll force navigation to the next slide as soon as the
span
width of the active indicator becomes 100%. With this addition, thedata-bs-pause="false"
attribute that we added earlier won’t play any role, so feel free to remove it if you want.
Here’s the extra JavaScript code needed for this functionality:
1 |
// 1
|
2 |
const carousel = new bootstrap.Carousel(myCarousel); |
3 |
|
4 |
function fillCarouselIndicator(index) { |
5 |
...
|
6 |
// 2
|
7 |
carousel.pause(); |
8 |
|
9 |
intervalID = setInterval(function () { |
10 |
...
|
11 |
|
12 |
if (i >= 100) { |
13 |
// 3
|
14 |
carousel.next(); |
15 |
}
|
16 |
}, 50); |
17 |
}
|
slide.bs.carousel
event that we used here, you could use the slid.bs.carousel
one as well. In such a case, you have to customize the code a little bit.
Conclusion
That’s it, folks! During this short exercise, we learned how to create unique Bootstrap carousels by converting their indicators into animated progress bars.
Hopefully, you found this technique beneficial and plan to incorporate it in one of your upcoming projects.
Once again, here’s what we built:
If you want to expand your Bootstrap knowledge, be sure to look at the constantly evolving Bootstrap resources here at Tuts+.
As always, thanks a lot for reading!
Bootstrap Templates on Envato Elements
- 20+ Best Bootstrap eCommerce Templates (for Your Online Store)Brenda Barron06 Oct 2022
- 15 Best Bootstrap Portfolio TemplatesFranc Lucas19 Jul 2021
- 20 Feature-Packed Bootstrap Admin TemplatesIan Yates10 Jun 2021
- 19 New Bootstrap Portfolio Templates for 2022Brenda Barron09 Sep 2021
- 18 Best Bootstrap Landing Page TemplatesBrenda Barron02 Sep 2021
- 15+ Best Bootstrap Website Templates (With Modern Designs)Hermione Wright13 Jul 2021
- 30 Amazing Bootstrap Templates to Try in 2023Paula Borowska10 May 2022