JSFiddle - React, Tailwind, and code Playground

CSS

.containsst {
  contain:strict;
}

.card {
    border: 1px solid;
    border-color: #e5e6e9 #dfe0e4 #d0d1d5;
    border-radius: 3px;
    background-color: #ffffff;
    font-family:"San Francisco", -apple-system, BlinkMacSystemFont, ".SFNSText-Regular", sans-serif;
    padding:12px;
    margin:12px;
    width: 500px;
    white-space:pre;
    
}

JavaScript

function randChar() {
    let chars = "0123456789abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQURSTUVWXYZ";
    return chars.substr( Math.floor(Math.random() * 62), 1);
}

function randContent() {
  let lines = 1 + (Math.random() * 20);
  let ret = '';
  for (let i = 0; i < lines; i ++) {
    let chars = 1 + (Math.random() * 20);
    for (let j = 0; j < chars; j ++) {
      ret += randChar();
    }
    ret += '\n';
  }
  return ret;
}

setInterval(function changeContents() {
  let i = 0;
 for (let x of document.getElementsByClassName('card')) {
   if (Math.random() < 0.01 && x.classList.contains('containsst')) {
      x.innerText = randContent();
       x.style.color = 'red'; 
   }
      
 }
}, 100);

var options = {
    rootMargin: '1000px',
}
var callback = function(entries, observer) { 
    for (let x of entries) {
      let t = x.target;
      if (x.intersectionRatio > 0) {
        
        t.style.height = "";

        
        t.classList.toggle("containsst", false);
      } else {
        
        // make sure contains is off while computing the height
        t.classList.toggle("containsst", false);
        
        t.style.height = window.getComputedStyle(t).height;

        t.classList.toggle("containsst", true);
      }
    }
};

for (let i = 0; i < 1000; i ++) {
  let div = document.createElement('div');
  div.innerText = randContent();
  div.classList.add('card');
  document.body.appendChild(div);
}


var observer = new IntersectionObserver(callback, options);
for (let x of document.getElementsByClassName('card'))
  observer.observe(x);