Home > OS >  How do I do this to the progress bar?(html-css)
How do I do this to the progress bar?(html-css)

Time:11-16

How do I do this to the progress bar like below:

enter image description here

.detail-load {
    height: 42px;
    border: 1px solid #A2B2C5;
    padding: 1px;
    border-radius: 10px;
}

.detail-load > .detail-loading {
    background: #904BFF;
    height: 100%;
    border-radius: 10px;
}

.detail-load-text {
    position: absolute;
    right: 0;
    left: 0;
    top: 10px;
    text-align: center;
    color: #fff;
    font-weight: 600;
    font-size: 17px;
}
<div class="detail-pop-item">
     <div class="detail-load">
         <div class="detail-loading" style="width: 80%;"></div>
     </div>
     <div class="detail-load-text">80%</div>
</div>

    
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

The progress bar I want to make is like the image I shared above. Can anyone help?

CodePudding user response:

You could use the clip-path property to achieve your desired result. I included some dummy javascript in the snippet to simulate loading.

const front = document.getElementById('progress-front');
const back = document.getElementById('progress-back');

let progress = 0;

setInterval(() => {
  front.style.webkitClipPath = `inset(0 0 0 ${progress}%)`;

  progress  ;

  if(progress >= 100) {
    progress = 0;
  }
  
  front.innerHTML = back.innerHTML = progress   "%";
}, 50);
.progress {
  position: relative;
  display: flex;
  font-size: 50px;
  border: 2px solid purple;
  overflow: hidden;
  width: 100%;
}

.back {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  background: purple;
  color: white;
}

.front {
  position: absolute;
  display: flex;
  justify-content: center;
  align-items: center;
  left: 0;
  width: 100%;
  right: 0;
  top: 0;
  bottom: 0;
  background: white;
  color: purple;
}
<div class="progress">
  <div class="back" id="progress-back">0%</div>
  <div class="front" id="progress-front">0%</div>
</div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

This is an example of what you want to accomplish:

https://codepen.io/robinrendle/pen/wKqmbW

<div class="wrapper">
  <div class="bg">
    <div class="el"></div>
  </div>
</div>
$loadingTime: 10s;
$color: rgb(255,0,0);

body {
  background-color: white;
}

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

@keyframes percentage { 
  @for $i from 1 through 100 {
    $percentage: $i   "%";
    #{$percentage} {
      content: $percentage;
    }
  }
}

.bg {
  background-color: $color;
  animation: loading $loadingTime linear infinite;
}

.el{
  color: $color;
  width: 200px;
  border: 1px solid $color;
  
  &:after {
    padding-left: 20px;
    content: "0%";
    display: block;
    text-align: center;
    font-size: 50px;
    padding: 10px 20px;
    color: rgb(0,255,255);
    mix-blend-mode: difference;
    animation: percentage $loadingTime linear infinite;
  }
}

html {
  height: 100%;
  background-color: white;
  font-family: 'PT Sans', sans-serif;
  font-weight: bold;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

The key item here is the mix-blend-mode property which defines how an element's content should blend with its background.

You can learn more about it here and here.

CodePudding user response:

Following Veselin's answer, you just need to change the color attributes as follows: $color: rgb(255,0,0); becomes $color: rgb(255,0,255); and

.el{
  ...
  &:after {
    ...
    color: rgb(0,255,255);
  }
}

becomes

.el{
  ...
  &:after {
    ...
    color: rgb(0,255,0);
  }
}

The result is:

$loadingTime: 10s;
$color: rgb(255,0,255);

body {
  background-color: white;
}

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

@keyframes percentage { 
  @for $i from 1 through 100 {
    $percentage: $i   "%";
    #{$percentage} {
      content: $percentage;
    }
  }
}

.bg {
  background-color: $color;
  animation: loading $loadingTime linear infinite;
}

.el{
  color: $color;
  width: 200px;
  border: 1px solid $color;
  
  &:after {
    padding-left: 20px;
    content: "0%";
    display: block;
    text-align: center;
    font-size: 50px;
    padding: 10px 20px;
    color: rgb(0,255,0);
    mix-blend-mode: difference;
    animation: percentage $loadingTime linear infinite;
  }
}

html {
  height: 100%;
  background-color: white;
  font-family: 'PT Sans', sans-serif;
  font-weight: bold;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

CodePudding user response:

I used a different approach, where you can set a CSS variable to control the length of the loading progress as well as displaying the value.

Because I used a pseudo-class to display the value, I needed to use a number hack, using counter-reset on the ::after pseudo-element.

As for having the dark text turn white, you can use mix-blend-mode: color-dodge. It's not perfect, as you can see, but perhaps good enough?

.detail-load {
  height: 42px;
  border: 1px solid #A2B2C5;
  padding: 1px;
  border-radius: 10px;
}

.detail-load > .detail-loading {
  background: #904BFF;
  height: 100%;
  border-radius: 10px;
  
  /* ADDED */
  width: calc(var(--progress) * 1%);
  position: relative;
}

.detail-load > .detail-loading::after {
  font-weight: 600;
  font-size: 17px;
  
  /* ADDED */
  counter-reset: number-hack var(--progress);
  content: counter(number-hack)"%";

  position: absolute;
  right: 0px;
  top: 50%;
  transform: translate(50%, -50%);
  
  color: #d2b6ff;
  mix-blend-mode: color-dodge;
}

.detail-load > .detail-loading.grey-text::after {
  color: #b5b5b5;
}
<div class="detail-pop-item">
  <div class="detail-load">
    <div class="detail-loading" style="--progress: 30"></div>
  </div>
</div>

<div class="detail-pop-item">
  <div class="detail-load">
    <div class="grey-text detail-loading" style="--progress: 60"></div>
  </div>
</div>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related