<h1>Color Changes according to completed percentage</h1>
<div style='--value:25; --min:0; --max:100;'>
<input type="range" min="0" max="100" value="25" oninput="this.parentNode.style.setProperty('--value', value)">
</div>
@supports(background:paint(paintWorketExample)){
// See Houdini compatibility table: https://developer.mozilla.org/en-US/docs/Web/CSS/@property#browser_compatibility
@property --color {
syntax: "<color>";
initial-value: magenta;
inherits: true;
}
}
div{
// number of possible keyframes states - see below
--frames: 4;
--completed: calc((var(--value) - var(--min) ) / (var(--max) - var(--min)) * 100);
--over-30: Clamp(0, var(--completed) - 30, 1);
--over-70: Clamp(0, var(--completed) - 70, 1);
--is-100: Calc( 1 - Clamp(0, 100 - var(--completed), 1) );
// select either frame 1, 2, 3, 4
// notice the placement of each part of the "max" items is very important
--frame: Max(
Calc(1 - var(--over-30)),
var(--over-30) * 2,
var(--over-70) * 3,
var(--is-100) * 4
);
// value msut not be below 1000ms for frame 1 to work
--delay: calc(-1s * ((var(--frame) - 1)/var(--frames)));
// the trick: switch between keyframes using the negative delay trick & sharp steps (2)
animation: states 1s var(--delay) paused;
// frames percentages must be evenly spread between 0% to 100%
@keyframes states {
0% { --color: salmon } // below 30% completion
25% { --color: gold } // below 70% completion
50% { --color: YellowGreen } // above 70% completion
100% { --color: green } // only at 100% completion
}
// progress bar
&::before{
--clip: inset(0 Calc(100% - var(--completed)*1%) 0 0%);
content: '';
position: absolute;
top:0;
right: 0;
bottom:0;
left:0;
clip-path: var(--clip);
background: var(--color); //currentColor;
border-radius: inherit;
transition: --color .1s;
}
// print current completed percentage
&::after{
counter-reset: x var(--value); // cannot use --progress since it's not true integer
content: counter(x)'%';
display: block;
margin-top: -2em;
text-align: center;
font-size: 2em;
top: -2em;
}
}
// IRRELEVANT STYLES:
body{
font-weight: 700;
height: 100vh;
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
}
h1{
color: #444;
font-size: 1.7em;
text-align: center;
}
input{
position: absolute;
z-index: 1;
opacity: 0;
top:0; right:0; bottom:0; left:0;
margin: auto;
height: 100%;
width: 100%;
cursor: ew-resize;
}
div{
background: #E1E1E1;
height: 50px;
width: 50%;
min-width: 300px;
position: relative;
margin: auto;
border-radius: 10px;
}
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.