Animated titles that fade in from left to right

In this post we create header where there are titles that are animated in by flying in from the left to right.

Every title has two parts.

The first title will be visible from the start. And also when JS is not run, the other titles will not be visible;

Codepen example

See the Pen Animated fade in from left titles by Wonky (@Wonky) on CodePen.

CSS

So the CSS is as follows:

header {
background: #bada55;
padding: 2.5rem 5rem;
max-width: 20rem;
margin: 0 auto;
}
.animated-titles {
margin-block-start: 2.5rem;
margin-block-end: auto;
display: grid;
/* Using grid we can lay the titles on top of each other, and it will use the max space if one title contains alot of characters. */
grid-template-areas: "title";
}

.title {
display: flex;
flex-direction: column;
gap: 1rem;
transition: opacity 0.2s ease-in-out;
opacity: 1;
margin: 0;

grid-area: title;

&:not(.active-title),
&.no-js
{
opacity: 0;
}
}

.animateDelay1 {
animation-delay: 0.5s;
}
.animateDelay2 {
animation-delay: 1s;
}
.fadeInLeft {
opacity: 0;
animation-name: fadeInLeft;
animation-fill-mode: forwards;
animation-duration: 0.5s;
animation-timing-function: ease-in;
}
@keyframes fadeInLeft {
from {
opacity: 0;
transform: translate3d(-100%, 0, 0);
}

to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}

HTML

<header class="animated-titles">
<h2 class="title active-title">
<span class="fadeInLeft animateDelay1">
Welcome to this codepen.
</span>
<span class="fadeInLeft animateDelay2">
This is the second title.
</span>
</h2>
<!-- Notice this has .no-js class. This is when js is somehow not enabled we only want to show first title group. -->
<h2 class="title no-js">
<span class="fadeInLeft animateDelay1">Javascript is awesome.</span>
<span class="fadeInLeft animateDelay2">CSS is amazing!</span>
</h2>

<h2 class="title no-js">
<span class="fadeInLeft animateDelay1">Have you seen display: grid?</span>
<span class="fadeInLeft animateDelay2">Grid is my favourite</span>
</h2>

<h2 class="title no-js">
<span class="fadeInLeft animateDelay1">Codepen.io</span>
<span class="fadeInLeft animateDelay2">Thank you!</span>
</h2>
</header>

JS

function initAnimatedTitles() {
const header = document.querySelector('.animated-titles');
const titles = header.querySelectorAll(".title");
// For each title create a timeout and set a class. Then remove class from 'others'.
// By replacing the animation runs again per placement.
let length = titles.length - 1;
let count = 1;
let delay = 5000;
setInterval(() => {
let titles = header.querySelectorAll(".title");
titles.forEach((el) => el.classList.remove("active-title"));
titles[count].classList.add("active-title");
let newOne = titles[count].cloneNode(true);
titles[count].parentNode.replaceChild(newOne, titles[count]);
if (count === length) {
count = 0;
} else {
count++;
}
}, delay);

// So when js is running, remove no-js classes;
titles.forEach((el) => el.classList.remove("no-js"));
}
document.addEventListener('DOMContentLoaded', initAnimatedTitles);

So this can be used for questions, where you ask a question in first part of title group. And answer it in the second part.

Thanks for reading, bye!