Typo Animation – Anim.js Split Effect
This animation splits text into letters, words, or lines and animates them individually as they enter the viewport. Once the attributes are applied, you can decide whether the effect runs letter by letter, word by word, or line by line. The delay and step options let you control the timing between each element, while the duration and offset define how quickly the animation plays and when it starts during scroll. The result is a smooth staggered reveal that gives your typography a dynamic and fluid appearance.
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.2/anime.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
var animatedElements = document.querySelectorAll('[data-letter-animate="true"]');
animatedElements.forEach(function(element) {
const mode = element.getAttribute('data-animate-mode') || 'letters';
const delayAttr = parseInt(element.getAttribute('data-delay')) || 0;
const stepDelayAttr = parseInt(element.getAttribute('data-step-delay')) || 50;
const animDurationAttr= parseInt(element.getAttribute('data-anim-duration'))|| 1000;
const offsetAttr = parseFloat(element.getAttribute('data-offset')) || 0;
// Préparation du texte
if (mode === 'letters' || mode === 'words') {
element.innerHTML = element.innerHTML
.replace(/(^|<\/?[^>]+>|\s+)([^\s<]+)/g, '$1<span class="letter-word">$2</span>');
const wordSpans = element.querySelectorAll('.letter-word');
wordSpans.forEach(function(wordSpan) {
if (mode === 'letters') {
wordSpan.innerHTML = wordSpan.textContent
.replace(/\S/g, "<span class='letter'>$&</span>");
} else {
wordSpan.classList.add('word');
}
});
} else {
const lines = element.innerHTML.trim()
.split('<br>');
element.innerHTML = lines
.map(line => `<span class="line">${line}</span>`)
.join('');
}
// Détection au scroll
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const target = entry.target;
let targets = target.querySelectorAll(
mode === 'letters' ? '.letter' :
mode === 'words' ? '.word' : '.line'
);
anime({
targets: targets,
translateY: [100, 0],
opacity: [0, 1],
easing: 'easeInOutQuad',
duration: animDurationAttr,
delay: (el, i) => delayAttr + stepDelayAttr * i,
begin: () => target.style.opacity = '1'
});
observer.unobserve(target);
}
});
}, {
threshold: 0,
rootMargin: `${-offsetAttr}% 0px ${-offsetAttr}% 0px`
});
observer.observe(element);
});
});
</script>
<style>
[data-letter-animate] {
opacity: 0;
}
.letter, .word, .line {
display: inline-block;
transform: translateY(100px);
opacity: 0;
}
.letter-word {
white-space: nowrap;
}
.line {
display: block;
overflow: hidden;
}
</style>
Adding Code to Webflow
You can copy HTML, JavaScript, or CSS directly from the examples on this site.
Once copied, there are two ways to add the code into your Webflow project:
- Embed Element :
Insert a Custom Code Embed block on your page and paste the code inside.
This is best for snippets that should run or display only in a specific section.
- Site-wide Custom Code :
Open Project Settings → Custom Code and paste the snippet into the Head or Before section. This is best for scripts and styles that must load on every page.