Search code examples
htmlcsscss-animationsbackground-imagelinear-gradients

How to create an animated rounded progress bar with linear gradient?


I want to create something like this using CSS only.

Rounded progress bar with gradient

More specifically, I need a div that has x% yellow background with rounded edges. This yellow part can be at the start, at the end or anywhere in the middle like the image above. Rest of the div should be colored black.

I know that I can do this by placing a div inside another and setting the length, position and background-color of the inner div. But I want to know if it can be done using only one div by setting its background-color or background-image or something else. Using linear-gradient I was able to achieve all I wanted except the rounded edge of the yellow part. Here is the CSS:

/* this will make the background-color 40% black, 20% yellow, 40% black */
div{
    background-image: linear-gradient(
        90deg,
        black 40%,
        yellow 20%,
        yellow 60,
        black 60%
    );
    background-size: 100% 100%;
    background-repeat: no-repeat;
}

And here is the code snippet:

#mydiv{
  width: 400px;
  height: 50px;
  background-image: linear-gradient(
        90deg,
        rgb(20, 20, 20) 40%,
        rgb(255, 174, 0) 20%,
        rgb(255, 174, 0) 60%,
        rgb(20, 20, 20) 60%
   );
   background-size: 100% 100%;
   background-repeat: no-repeat;
   border-radius: 25px;
}
<div id="mydiv"></div>

Is it possible to achieve this using one div and CSS only?

I need to be able to control the length and position of the yellow part so that I can change its position and length in a CSS animation.

The animation will look like this:

#outer{
  width: 400px;
  height: 20px;
  border-radius: 10px;
  position: relative;
  overflow: hidden;
  background-color: rgb(20, 20, 20);
}

#inner{
  width: 20%;
  height: 100%;
  border-radius: 10px;
  position: absolute;
  left: -20%;
  background-color: rgb(255, 174, 0);
  animation: loading 2s infinite;
}

@keyframes loading{
  0%{
    left: -20%;
  }
  100%{
    left: 100%;
  }
}
<div id="outer">
  <div id="inner"></div>
</div>


Solution

  • To accomplish this, it is needed to make the yellow bar as an independent selector.

    And using css, you can use :before selector inside #mydiv tag and place the yellow bar there as follows.

    #mydiv {
      width: 400px;
      height: 50px;
      background-color: black;
      border-radius: 25px;
      position: relative;
    }
    
    #mydiv:before {
      content: " ";
      position: absolute;
      top: 0;
      left: 20%;
      width: 40%;
      height: 100%;
      border-radius: 25px;
      background-color: yellow;
    }
    <div id="mydiv"></div>