Skip to content
Advertisement

Bug using keyframes on bootstrap progress bar

I’m trying to animate a Bootstrap 5 progress bar when my page loads. This seems to work, but on the other hand it overrides the basic bootstrap animation.

https://codepen.io/Gwentey/pen/gOeQVGZ

Here is a snippet to view the problem I am having. When you load the page, the progress bar goes from 0% to 20% and the animation no longer works…

When you load the page, the progress bar goes from 0% to 20% and the animation no longer works… When the page loads I want there to be an animation from 0 to 20 (working but stops the animation). Then the user has to click to get to 40, then 60, then 80, and finally 100. My problem is that the animation I added overwrites (I believe) Bootstrap’s animation. So when the user goes from 20 to 40 (with the button) there is no effect, and it creates an abrupt change… (see codepen snippet)

CSS :

.level-20 {
  width: 20%;
  animation: effetChargement 1s forwards;
}
.level-40 {
  width: 40%;
}
.level-60 {
  width: 60%;
}
.level-80 {
  width: 80%;
}
.level-100 {
  width: 100%;
}

@keyframes effetChargement {
  0% {
    width: 0%;
  }
  100% {
    width: 20%;
  }

}

HTML :

<div class="progress" style="height: 20px">
  <div
     id="bar"
    class="progress-bar progress-bar-striped progress-bar-animated level-20"
    role="progressbar"
    aria-valuemin="0"
    aria-valuemax="100"
  ></div>
</div>
<button type="button" class="btn btn-primary my-3">Click to change level</button>

I do not put the javascript because it only serves to detect the click on the button and passed from level (level-20 -> level-40 -> level-60 -> level-80 -> level-100)

Thanks in advance

Advertisement

Answer

I would use an transition instead of keyframes (and add the initial class using js):

window.addEventListener('load', (event) => {
  const button = document.querySelector('button');
  const bar = document.getElementById('bar');
  bar.classList.add('level-20');

  button.addEventListener('click', event => {
    if (bar.classList.contains("level-20")) {
      bar.classList.remove("level-20");
      bar.classList.add("level-40");
    } else if (bar.classList.contains("level-40")) {
      bar.classList.remove("level-40");
      bar.classList.add("level-60");
    } else if (bar.classList.contains("level-60")) {
      bar.classList.remove("level-60");
      bar.classList.add("level-80");
    } else if (bar.classList.contains("level-80")) {
      bar.classList.remove("level-80");
      bar.classList.add("level-100");
    }
  });
});
@import url('https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css');
.progress-bar {
  width: 0;
  transition: width 1s ease-in-out;
}

.level-20 {
  width: 20%;
}

.level-40 {
  width: 40%;
}

.level-60 {
  width: 60%;
}

.level-80 {
  width: 80%;
}

.level-100 {
  width: 100%;
}
<div class="progress" style="height: 20px">
  <div id="bar" class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<button type="button" class="btn btn-primary my-3">Click to change level</button>
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement