I’m looking for an effect like the primary one on this page https://sendgrid.com/
The page shows a centered sentence, a word is replaced, the sentence parts left and right to the word, smoothly readjust position according to the new word width.
<body>
    <h1>
        This animation is
        <span id="swappable">awesome</span>
        don't you think?
    </h1>
</body>
body {
    display: flex;
    justify-content: center;
}
#swappable {
    display: inline-block;
}
const swappables = ["bad", "great", "fantastic", "boring"];
let index = 0;
setInterval(() => {
    document.getElementById("swappable").innerHTML = swappables[index];
    index = index == swappables.length - 1 ? 0 : index + 1;
}, 3000);
This code makes the parts snap into place after a word is replaced but
How can I achieve this smooth transition?
Advertisement
Answer
document.addEventListener('DOMContentLoaded',()=>{
const stringsCont = document.querySelector('#strings-cont');
const strings = [...stringsCont.querySelectorAll('.string')];
let active = 0;
next = () =>{
strings.forEach((s,i) => i===active?s.classList.add('active'):s.classList.remove('active'));
  stringsCont.style.width = strings[active].offsetWidth+'px';
  active = (active+1)%strings.length;
}
setInterval(next, 3000);
setTimeout(next,0)
});h1 {
  font-family: sans-serif;
  font-size: 16px;
  text-align: center;
  font-weight: normal;
  display: flex;
  align-items: center;
  justify-content: center;
}
#strings-cont{
  position: relative;
  display: inline-flex;
  transition: width .3s ease;
  justify-content: center;
}
.string {
  font-weight: bold;
  transition: opacity .3s ease, top .3s ease;
  position: absolute;
  opacity:0;
  left: 50%;
  top: 100%;
  transform: translateX(-50%);
  white-space: nowrap;
}
.string:before {
  content: '';
  position: absolute;
  top: 100%;
  left:0;
  height: 3px;
  width: 0;
  background-color: violet;
}
.string.active {
  transition: opacity .3s ease;
  opacity:1;
  position: static;
  transform: translateX(0);
  left:0;
  top:0;
}
.string.active:before {
  width: 100%;
  transition: all 2.7s ease;
  transition-delay: .3s;
}<h1> Send Email  <span id="strings-cont" style="width:0"> <span class="string">Lorem Ipsum</span> <span class="string">Dolor Sit Ammet</span> <span class="string">Consectetur Adipiscing Elit</span> <span class="string">Sed Do Eiusmod</span> </span>  With Confidence </h1>