riccardo
riccardo

Reputation: 309

How to create a gradient progress bar with a fixed gradient

I'm rather new to HTML and CSS. I'd like to create a progress bar that has a gradient background which it masked to the whole element but only visible on the bar itself. So far I've only managed to get the result shown below 1. Ive tried to achieve the result shown in the second image by manipulating other background properties such as background-attachment, but then the gradient itself does not fit anymore. I've also tried to give the parent of the bar a gradient background and simply draw a white div above the remaining space but that solution prohibited me from adding a border radius to the bar itself. Any help is highly appreciated. Cheers!

What I'm trying to achieve

What I've got so far

.progress-bar-container {
  width: 500px;
  height: 50px;
  margin: 50px 0px;
  background: black;
}

.progress-bar-indicator {
  height: 100%;
  background-image: linear-gradient(to right, red, green, blue);
  border-radius: 25px;
}

#indicator-1 {
  width: 80%;
}

#indicator-2 {
  width: 50%;
}

#indicator-3 {
  width: 20%;
}
<div class="progress-bar-container">
  <div class="progress-bar-indicator" id="indicator-1"></div>
</div>

<div class="progress-bar-container">
  <div class="progress-bar-indicator" id="indicator-2"></div>
</div>

<div class="progress-bar-container">
  <div class="progress-bar-indicator" id="indicator-3"></div>
</div>

Upvotes: 5

Views: 16358

Answers (3)

Temani Afif
Temani Afif

Reputation: 273379

A solution using mask that will work with dynamic width:

.progress-bar-container {
  height: 50px;
  margin: 50px 0px;
  background: black;
  position:relative; /* relative here */
}

.progress-bar-indicator {
  height: 100%;
  border-radius: 25px;
   /* this will do the magic */
  -webkit-mask:linear-gradient(#fff 0 0);
          mask:linear-gradient(#fff 0 0);
}
.progress-bar-indicator::before {
  content:"";
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background-image: linear-gradient(to right, red, green, blue); /* your gradient here */
}
<div class="progress-bar-container">
  <div class="progress-bar-indicator" style="width:80%"></div>
</div>

<div class="progress-bar-container">
  <div class="progress-bar-indicator" style="width:50%"></div>
</div>

<div class="progress-bar-container">
  <div class="progress-bar-indicator" style="width:30%"></div>
</div>

Upvotes: 9

Ahmad Habib
Ahmad Habib

Reputation: 2382

#container {
  width: 800px;
  height: 60px;
  margin: 0 auto;
  position: relative;
  top: 50px;
  transform: translateY(-50%);
  border-radius: 35px;
  overflow: hidden;
}

.child {
  width: 100%;
  height: 100%;
}

.progress {
  color: white;
  text-align: center;
  line-height: 75px;
  font-size: 35px;
  font-family: "Segoe UI";
  animation-direction: reverse;
  background: #e5405e;
  /* Old browsers */
  background: -moz-linear-gradient(left, #e5405e 0%, #ffdb3a 25%, #3fffa2 50%, #3fffa2 50%, #1a9be0 73%, #ba68ed 100%);
  /* FF3.6-15 */
  background: -webkit-linear-gradient(left, #e5405e 0%, #ffdb3a 25%, #3fffa2 50%, #3fffa2 50%, #1a9be0 73%, #ba68ed 100%);
  /* Chrome10-25,Safari5.1-6 */
  background: linear-gradient(to right, #e5405e 0%, #ffdb3a 25%, #3fffa2 50%, #3fffa2 50%, #1a9be0 73%, #ba68ed 100%);
}

.shrinker {
  background-color: black;
  position: absolute;
  top: 0;
  right: 0;
  width: 100%;
}

.timelapse {
  animation-name: timelapse;
  animation-fill-mode: forwards;
  animation-duration: 5s;
  animation-timing-function: cubic-bezier(.86, .05, .4, .96);
}

@keyframes timelapse {
  0% {
    width: 100%;
  }

  100% {
    width: 0%;
  }
}
<div id="container">
        <div class="child progress"></div>
        <div class="child shrinker timelapse"></div>
</div>

Working Fiddle

Upvotes: 1

doğukan
doğukan

Reputation: 27461

Keep the gradient width the same as the container width.

.progress-bar-container {
  width: 500px;
  height: 50px;
  margin: 50px 0px;
  background: black;
}

.progress-bar-indicator {
  height: 100%; 
  background-image: linear-gradient(to right, red, green, blue);
  /*                ↓ same as container width */  
  background-size: 500px 100%;
  border-radius: 25px;
}

#indicator-1 {
  width: 80%;
}

#indicator-2 {
  width: 50%;
}

#indicator-3 {
  width: 20%;
}
<div class="progress-bar-container">
  <div class="progress-bar-indicator" id="indicator-1"></div>
</div>

<div class="progress-bar-container">
  <div class="progress-bar-indicator" id="indicator-2"></div>
</div>

<div class="progress-bar-container">
  <div class="progress-bar-indicator" id="indicator-3"></div>
</div>

Upvotes: 2

Related Questions