Typing animations can add personality to your website, draw attention to important messages, or simply create a more dynamic user experience.
The best part? You can create impressive typing effects using nothing but CSS. So in this article I will break it down step by step.
The Magic Behind CSS Typing Animations
CSS typing animations rely on a clever combination of techniques. The core principle involves controlling the width
of a text container and using the steps()
timing function to create that distinctive character-by-character reveal.
Think of it like slowly opening a window blind, instead of a smooth transition, you're revealing the content in discrete chunks.
The typical setup involves a container with overflow: hidden
and a width that animates from 0 to the full width of the text. The steps()
function ensures the animation jumps from one character position to the next, rather than smoothly sliding.
Basic Typing Animation Setup
Start animation
This is typewritten text right here.
Here's the foundation for a simple typing effect. The animation will begin once the active
class has been added to the targeted element.
.typewriter {
font-family: 'Courier New', monospace;
overflow: hidden;
white-space: nowrap;
width: 0;
}
.typewriter.active{
animation: typing 3s steps(40, end) forwards;
}
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
The steps(40, end)
parameter tells the animation to complete in 40 discrete steps, which works well for text around 40 characters long.
You'll need to adjust this number based on your actual text length.
Adding the Blinking Cursor
No typing animation feels complete without that classic blinking cursor at the end. You can create this effect using a CSS pseudo-element:
.typewriter::after {
content: '|';
animation: blink 1s infinite;
}
@keyframes blink {
0%, 50% { opacity: 1; }
51%, 100% { opacity: 0; }
}
Some developers prefer using an underscore or a block character instead of the pipe symbol. The choice often depends on the font and overall design aesthetic.
Multiple Line Typing Effects
Creating multi-line typing animations requires a bit more creativity. One approach involves staggering multiple animations with different delays:
.line1 {
animation: typing 2s steps(20, end) 0s forwards;
}
.line2 {
animation: typing 2s steps(25, end) 2.5s forwards;
}
.line3 {
animation: typing 2s steps(30, end) 5s forwards;
}
Each line starts after the previous one completes, creating a natural flow of text appearing.
Start animation
this is the first line
this is the second line
this is the third line
Depending on the length of your sentences, you will probably need some fine-tuning to each of the animation steps.
Enhancing with Sound-Like Timing
To make your typing animation feel more realistic, consider varying the timing slightly. Real typing isn't perfectly consistent.
Start animation
This is a slower sentence...
but this part types super fast!
And... pause for dramatic effect.
People pause at punctuation and type common words faster. While pure CSS has limitations here, you can create variations by adjusting the steps()
value and duration for different words or phrases.
Here's an example where each phrase has a slightly different typing speed, creating a more "human" feel:
<span class="btn" onclick="document.querySelectorAll('.sound-like').forEach(el => el.classList.add('active'))">
Start animation
</span>
<div class="sound-like slow">This is a slower sentence...</div>
<div class="sound-like fast">but this part types super fast!</div>
<div class="sound-like pause">And... pause for dramatic effect.</div>
.sound-like {
font-family: 'Courier New', monospace;
overflow: hidden;
white-space: nowrap;
width: 0;
display: block;
margin-bottom: 8px;
}
.sound-like.slow.active {
animation: typing-slow 3s steps(40, end) forwards;
}
.sound-like.fast.active {
animation: typing-fast 1.5s steps(25, end) 3.2s forwards;
}
.sound-like.pause.active {
animation: typing-pause 4s steps(35, end) 5s forwards;
}
@keyframes typing-slow {
from { width: 0; }
to { width: 100%; }
}
@keyframes typing-fast {
from { width: 0; }
to { width: 100%; }
}
@keyframes typing-pause {
from { width: 0; }
to { width: 100%; }
}
In this example:
The first sentence types slowly to draw attention.
The second sentence speeds up to simulate confidence or familiarity.
The third sentence introduces a longer delay, mimicking a natural pause before continuing.
By chaining different durations and delays, you simulate the unpredictable rhythm of real typing and make the effect feel more "alive."
CSS typing animations are generally lightweight, but there are a few things to keep in mind. Avoid animating too many elements simultaneously, as this can impact performance on slower devices.
Also, consider using will-change: width
on your animated elements to hint to the browser that optimization is needed.
Accessibility and User Experience
Not everyone enjoys animations, and some users find them distracting or problematic. Always respect the prefers-reduced-motion
media query:
@media (prefers-reduced-motion: reduce) {
.typewriter {
animation: none;
width: 100%;
}
}
This ensures users who have indicated they prefer reduced motion will see the text instantly rather than animated.
Creative Variations
Once you've mastered the basics, there are numerous ways to enhance your typing animations. You can create deletion effects by reversing the animation, add color changes as text appears, or combine typing with other CSS animations for more complex effects.
Some designers create "glitch" effects during typing, simulate different typing speeds for different characters, or even create the illusion of backspacing and correcting mistakes.
If you enjoy creating engaging visual effects with pure CSS, you might also want to explore CSS-Only Tooltips for another interactive element that doesn't require JavaScript.
Browser Support and Fallbacks
CSS typing animations work well across modern browsers, but older versions might not support all features.
The core animation properties have excellent support, but always test your implementations across different browsers and devices.
For critical content, ensure your text is readable even if the animation fails to load. The text should appear normally if CSS animations aren't supported.
Wrapping Up
CSS typing animations offer a fantastic way to add personality and engagement to your web projects without requiring JavaScript. They're relatively simple to implement, highly customizable, and can significantly improve the visual appeal of your content.
For more CSS techniques that enhance user interfaces, check out my guide on implementing Glassmorphism design - another modern visual effect that pairs well with subtle animations.