Chatbot typing animation

by anoopsuda

HTML

<div class="chatbot">

  <div class="msg-1">Hi there 👋</div>

  <div class="msg-2">I'm here to help you create your innovation story submission - quick, guided, and easy.</div>

  <div class="msg-3">Would you like to get started?</div>

  <div class="btnset">
    <button>Yes</button>
    <button>No</button>
  </div>

</div>

CSS

.chatbot {
  padding:16px; 
  height:250px; 
  width:250px; 
  box-shadow:0 0 5px #ccc;
  position: relative;
  overflow: hidden;
}

/* Base styling */
.msg-1, .msg-2, .msg-3, .btnset {
  background:#fff;
  padding:8px;
  border-radius:6px;
  box-shadow:0 0 4px #ddd;
  margin:0 0 8px 0;
  max-width:200px;

  /* fully hidden initially */
  opacity:0;
  transform: translateY(30px);
}

/* Activated when typing begins */
.show {
  animation: slideUp 0.7s ease forwards;
}

button {
  padding:6px 12px;
  border:none;
  border-radius:5px;
  cursor:pointer;
  box-shadow:0 0 4px #ddd;
}

/* Animation keyframes */
@keyframes slideUp {
  0% { opacity:0; transform: translateY(30px); }
  100% { opacity:1; transform: translateY(0); }
}

JavaScript

function typeText(element, speed = 25, callback) {
  const fullText = element.textContent;
  element.textContent = "";
  let i = 0;

  function typing() {
    if (i < fullText.length) {
      element.innerHTML += fullText.charAt(i);
      i++;
      setTimeout(typing, speed);
    } else if (callback) {
      callback();
    }
  }
  typing();
}

// Sequence timing
setTimeout(() => {
  const el1 = document.querySelector('.msg-1');
  el1.classList.add("show");
  typeText(el1);
}, 200);

setTimeout(() => {
  const el2 = document.querySelector('.msg-2');
  el2.classList.add("show");
  typeText(el2);
}, 1500);

setTimeout(() => {
  const el3 = document.querySelector('.msg-3');
  el3.classList.add("show");
  typeText(el3);
}, 4500);

setTimeout(() => {
  const btns = document.querySelector('.btnset');
  btns.classList.add("show");
}, 5500);