Text Swap Animation
Monospace status text that blurs out and in letter by letter when the phrase changes. Click the button to cycle phrases.
Preview and code
index.html
<div class="tx"><div class="ph"></div><button type="button">Next phrase</button></div>
styles.css
.tx{width:100%;height:100%;min-height:380px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:22px;font-family:system-ui,-apple-system,sans-serif;color:#eee;}.ph{font:500 18px ui-monospace,SFMono-Regular,monospace;height:28px;white-space:pre}.ph span{display:inline-block;animation:ci .5s cubic-bezier(.3,1.2,.5,1) both}.ph.o span{animation:co .3s ease both}@keyframes ci{from{opacity:0;filter:blur(6px);transform:translateY(8px)}to{opacity:1;filter:none;transform:none}}@keyframes co{to{opacity:0;filter:blur(6px);transform:translateY(-8px)}}.tx button{background:#1b1b1b;border:1px solid #2a2a2a;color:#eee;border-radius:99px;padding:8px 16px;font:600 12px system-ui;cursor:pointer;transition:transform .2s}.tx button:active{transform:scale(.95)}
script.js
(function(){var R=document.querySelector(".tx"),ph=R.querySelector(".ph"),P=["Inspecting the repository","Planning the changes","Writing the component","Running the tests","Shipping the fix"],i=0,busy=false;function put(t){ph.className="ph";ph.innerHTML="";t.split("").forEach(function(c,k){var s=document.createElement("span");s.textContent=c;s.style.animationDelay=k*22+"ms";ph.appendChild(s)})}R.querySelector("button").onclick=function(){if(busy)return;busy=true;[].forEach.call(ph.children,function(s,k){s.style.animationDelay=k*10+"ms"});ph.className="ph o";setTimeout(function(){i=(i+1)%P.length;put(P[i]);busy=false},420)};put(P[0])})();