How do I do this to the progress bar like below:
.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>