Search code examples
cssanimationprogress

How to make an animate progress bar with startup animation using css


I am trying to implement an animated progress bar with startup animation.

The problem is that I am using transform: translateX(-100%); that make ugly effect - progress bar is outside progress area.

Core:

@keyframes slideInFromLeft {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(0);
  }
}

.progress {
    width:200px;
    height:50px;
    border:1px solid black;
    position:relative;
}

.child {  
    background:black;
    width: 50%;
    height: 100%;
    animation: 1s ease-out 0s 1 slideInFromLeft;
} 
<div class="progress">
  <div class="child">x</div>
</div>

How can I fix this ugly effect? Or is there any better way?


Solution

  • Have a look at CSS position property, you need position relative and position absolute.

    Then the animation-fill-mode

    forwards The target will retain the computed values set by the last keyframe encountered during execution. The last keyframe depends on the value of animation-direction and animation-iteration-count:

    @keyframes slideInFromLeft {
      to{ width: 50%; }
    }
    
    .progress {
        width:200px;
        height:50px;
        border:1px solid black;
        position:relative;
    }
    
    .child {  
        position:absolute;
        left:0;
        top:0;
        background:black;
        width: 0%;
        height: 100%;
        overflow:hidden;
        animation: slideInFromLeft 1s ease forwards;
    } 
    <div class="progress">
      <div class="child">x</div>
    </div>

    Now if you want to animate it using translate you have to add overflow:hidden to the parent element

    @keyframes slideInFromLeft {
      from {
        transform: translateX(-100%);
      }
    }
    
    .progress {
        width:200px;
        height:50px;
        border:1px solid black;
        position:relative;
        overflow:hidden
    }
    
    .child {  
        background:black;
        width: 50%;
        height: 100%; 
        transform: translateX(0%);
        animation: slideInFromLeft 1s ease;
    } 
    <div class="progress">
      <div class="child">x</div>
    </div>