I was playing around with CSS scroll-driven animations a little bit today and made a neat heart rate progress indicator using only CSS. As you scroll down the page the heart rate reading progresses.

animation-timeline is not currently supported in all browsers, including Firefox, so if the example below doesn't work, that's why.

See the Pen CSS scroll-driven ekg animation by Zach Patrick (@zpthree) on CodePen.

This is obviously a very rudimentary example of what can be done using scroll-driven animations.

The HTML is pretty simple. It's just a heart rate SVG and a skull that shows up when the heart rate stops.

html

<body>
  <div class="ekg">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 400" role="img" aria-label="ECG line starting with flatline"><path fill="none" stroke="crimson" stroke-width="22" d="M 0 210 L 300 210 Q 325 210 340 175 Q 350 150 365 175 Q 385 210 420 210 L 445 210 L 465 285 L 485 160 L 520 60 L 555 330 L 590 210 Q 615 210 630 190 Q 650 165 675 190 Q 705 220 735 210 L 770 210 Q 800 210 820 170 Q 840 130 870 170 Q 900 215 935 210 L 960 210 L 1200 210"/></svg>
    <p class="dead">💀</p>
  </div>
</body>

I did add a little bit of JavaScript just so I could get the length of the SVG's path and set the SVG's stroke-dasharray and stroke-dashoffset values dynamically.

javascript

const path = document.querySelector(".ekg path");
const length = path.getTotalLength();
path.style.strokeDasharray = length;
path.style.strokeDashoffset = length;

The path of the SVG starts completely hidden and, as you scroll, gets drawn until it's completely visible. The stroke-dashoffset is the amount of the path that still needs drawn, so animating that to zero simulates the heart rate.

Then I used the CSS scroll() function to hook into the page's scroll bar and animate the heart rate based on the scroll bar position.

css

path {
  animation: draw linear;
  animation-duration: 1ms;
  transform-origin: left;
  animation-timeline: scroll();
}

@keyframes draw {
  50%  { 
    opacity: 100%;
    stroke-dashoffset: 0; 
  }
  
  100% {
    opacity: 0;
    stroke-dashoffset: 0; 
  }
}

Unfortunately, the animation-timeline property that enables this CSS-only approach is currently not yet available in all browser.