<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

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.