Skip to content
Advertisement

css replace word in centered sentence and have the width smoothly readjust

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&nbsp;
<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> 
&nbsp;With Confidence
</h1>
Advertisement