<label>
  <div>animation-delay</div>
  <p>Controls the <code>delay</code> property of the animation using negative value</p>
  <input type="range" min="-100" max="0" value="-100" oninput="this.parentNode.style.setProperty('--delay', `${value}s`)">
</label>

<label>
  <span>select keyframe</span>
  <p>Selects a specific keyframe by calculating the the negative <code>delay</code> value needed</p>
  <input type="range" min="1" max="3" value="1" oninput="this.parentNode.style.setProperty('--frame', value)">
</label>

<label>
  <span>select keyframe</span>
  <p>Same as above with slighly different calculation and keyframes offsets</p>
  <input type="range" min="1" max="3" value="1" oninput="this.parentNode.style.setProperty('--frame', value)">
</label>
:root{
  --frames: 3; // needed for calculating the exact delay which will pasue on the desired keyframe
}

////////////////////////////////////////////////////////////////////////
// Full-range negative delay between -100s to 0s

label:nth-of-type(1){ 
  // the (absolute) delay must not be equal or bigger than the duration
  animation: states1 100.001s var(--delay, 0s) paused; 
}

@keyframes states1 {
    0% { color: red; --frame:"1"; }         
   50% { color: green; --frame:"2"; }        
  100% { color: blue; --frame:"3"; } 
}


////////////////////////////////////////////////////////////////////////
// Exact delay. Requires keyframes to be written at specific intervals
// (my preferred method)

label:nth-of-type(2){ 
  --delay: calc(-1s * ((var(--frame, 1) - 1) / var(--frames))); 
  animation: states2 1s var(--delay) paused; 
}

@keyframes states2 {
    0% { color: red; --frameStr:"1"; }    // take affect between 0% to 33%      
   33% { color: green; --frameStr:"2"; }  // take affect between 33% to 66%  
   66% { color: blue; --frameStr:"3"; }   // take affect between 66% to 100%  
}


////////////////////////////////////////////////////////////////////////
// Exact delay. Requires keyframes to be written at specific intervals.
// Also requires the delay to be just a bit lower than the duration (for last frame)
// (can also be the other way around)

label:nth-of-type(3){ 
  // Example, for "--frame:2":
  // -0.999 * (2-1) / (3-1) => -0.999 * 1 / 2 => -0.499 (green keyframe range)
  --delay: calc(-.999s * ((var(--frame, 1) - 1) / (var(--frames) - 1))); 
  animation: states3 1s var(--delay) paused; 
}

@keyframes states3 {
    0% { color: red; --frameStr:"1"; }         
   50% { color: green; --frameStr:"2"; }        
  100% { color: blue; --frameStr:"3"; } 
}





body{
  display: grid;
  place-items: center;
  font-weight: 700;
  height: 100vh;
  user-select: none;
}

label{
  display: flex;
  align-items: center;
  flex-flow: column;
  
  > span::after{ content: " " var(--frameStr) "/3"; }
  > span, > div{ font-size: 2em; }
  > p{ color: black; }
}

code{ background:lightyellow; padding: 0 4px; }
input{ width: 300px; }
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.