Text & Typography
Text effects, kinetic typography, splitting and variable fonts.
Updated
How do you animate text without hurting readability or SEO?
Text effects animate headlines and words: gradients, typewriter reveals, glitches, letter-by-letter entrances, variable-font weight changes. They use background-clip: text, @keyframes and variable-font axes, plus a small script that splits a heading into one span per character when each letter has to move on its own.
How to choose, performance and accessibility
- Keep them for short, prominent text: Animated Gradient or Typing Effect for a hero title, Letter Fade In for a tagline, Neon Flicker for an event page.
- Leave the real text in the HTML so search engines and screen readers read it normally; when a heading is split into letters, keep an
aria-labelwith the full phrase. - Avoid animating long paragraphs, and show the final state immediately for
prefers-reduced-motion. - Animated Gradient, Typing Effect, Letter Fade In and Weight Breathing are free with their full code; the rest come with Premium.
View source code
<div class="demo-preview">
<span class="demo-text text-animated-gradient">Gradient Flow</span>
</div>.demo-preview,
.demo-preview *,
.demo-preview *::before,
.demo-preview *::after {
box-sizing: border-box
}
.demo-preview {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 250px;
overflow: hidden;
position: relative;
background: rgb(26, 26, 36);
color: rgb(255, 255, 255);
font-family: sans-serif;
}
.demo-text {
font-size: 2.5rem;
font-weight: 800;
letter-spacing: -0.02em;
}
.text-animated-gradient {
background: linear-gradient(90deg, #6366f1, #8b5cf6, #d946ef, #6366f1);
background-size: 300% 100%;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: gradientMove 4s linear infinite;
}
.demo-text span {
display: inline-block;
}
@keyframes gradientMove {
0% {
background-position: 0% 50%;
}
100% {
background-position: 300% 50%;
}
}/* Pure CSS — no JavaScript required */View source code
<div class="demo-preview">
<span class="demo-text text-typing">Hello World</span>
</div>.demo-preview,
.demo-preview *,
.demo-preview *::before,
.demo-preview *::after {
box-sizing: border-box
}
.demo-preview {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 250px;
overflow: hidden;
position: relative;
background: rgb(26, 26, 36);
color: rgb(255, 255, 255);
font-family: sans-serif;
}
.demo-text {
font-size: 2.5rem;
font-weight: 800;
letter-spacing: -0.02em;
}
.text-typing {
overflow: hidden;
border-right: 3px solid #6366f1;
white-space: nowrap;
animation: typing 3s steps(20) infinite, blink 0.5s step-end infinite alternate;
width: 0;
max-width: fit-content;
}
.demo-text span {
display: inline-block;
}
@keyframes typing {
0%,
90%,
100% {
width: 0;
}
30%,
60% {
width: 100%;
}
}
@keyframes blink {
50% {
border-color: transparent;
}
}/* Pure CSS — no JavaScript required */View source code
<div class="demo-preview">
<span class="demo-text text-fade-in" id="fadeInText"></span>
<button class="replay-btn" onclick="replayFadeIn()">Replay</button>
</div>.demo-preview,
.demo-preview *,
.demo-preview *::before,
.demo-preview *::after {
box-sizing: border-box
}
.demo-preview {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 250px;
overflow: hidden;
position: relative;
background: rgb(26, 26, 36);
color: rgb(255, 255, 255);
font-family: sans-serif;
}
/* Variables du design system du site, dont ce code dépend (valeurs de css/style.css — à adapter librement). */
.demo-preview {
--primary-light: #818cf8;
--radius-md: 0.5rem;
--transition-fast: 150ms ease;
}
.demo-text {
font-size: 2.5rem;
font-weight: 800;
letter-spacing: -0.02em;
}
.text-fade-in span {
opacity: 0;
animation: fadeInLetter 0.5s ease forwards;
}
.replay-btn {
position: absolute;
bottom: 15px;
right: 15px;
padding: 8px 16px;
background: rgba(99, 102, 241, 0.2);
border: 1px solid rgba(99, 102, 241, 0.4);
border-radius: var(--radius-md);
color: var(--primary-light);
font-size: 0.8rem;
font-weight: 500;
cursor: pointer;
transition: all var(--transition-fast);
}
.replay-btn:hover {
background: rgba(99, 102, 241, 0.4);
transform: scale(1.05);
}
.demo-text span {
display: inline-block;
}
@keyframes fadeInLetter {
to {
opacity: 1;
}
}(function() {
function splitText(element, text, delayStep = 0.05) {
element.innerHTML = text.split('').map((char, i) => {
if (char === ' ') return ' ';
return `<span style="animation-delay: ${i * delayStep}s">${char}</span>`;
}).join('');
}
function initFadeIn() {
const el = document.getElementById('fadeInText');
splitText(el, 'FADE IN', 0.08);
}
function replayFadeIn() {
const el = document.getElementById('fadeInText');
el.innerHTML = '';
setTimeout(() => initFadeIn(), 50);
}
initFadeIn();
window.replayFadeIn = replayFadeIn;
})();Scatter to Word
Characters fly from random positions and assemble into a word on load or click.
Effect page →Wave Text
Each letter oscillates vertically with offset timing creating a continuous wave.
Effect page →Typewriter Glitch
Classic typewriter with random glitch interruptions (character swaps, flickers).
Effect page →Text Shuffle Reveal
Characters rapidly cycle through random letters before locking into the correct one.
Effect page →Parallax Depth Text
Multi-layered text moving at different speeds on mouse movement, creating 3D depth.
Effect page →Text Explosion
Click to scatter characters with physics, click again to reassemble them.
Effect page →