4 Pure CSS3 with JSPublished 2026-10-05Free · no sign-up
Seven typing effects: classic typing with steps(), two lines typed in turn, a headline that types and deletes words, a terminal command with output, a caret blinking after a heading, a typo that gets corrected and a chat bubble that shows typing dots before the message.
The text reveals one character at a time because its width animates in steps() from 0 to the text's length in ch units, and a border on the right blinks as the caret. It needs a monospace font so every character is exactly 1ch wide.
The second line starts typing only after the first has finished, using an animation delay equal to the first line's duration. The caret moves with the typing because only the line currently being typed shows it.
View code
<div class="ty2"><p class="a">Hello, I'm Sam.</p><p class="b">I build fast shops.</p></div>
A headline types a word, pauses, deletes it and types the next, in a loop. Screen readers get one static sentence listing every word, and the moving part is aria-hidden, because a constantly changing word would be read over and over.
View code
<h3 class="ty3"><span class="sr">We design websites, online shops and mobile apps.</span><span aria-hidden="true">We design <span class="w"></span><span class="c">|</span></span></h3>
var el = document.querySelector('.ty3 .w'), words = ['websites', 'online shops', 'mobile apps'], i = 0, n = 0, del = false;
if (matchMedia('(prefers-reduced-motion: reduce)').matches) { el.textContent = words[0]; } else (function tick() {
var w = words[i]; n += del ? -1 : 1; el.textContent = w.slice(0, n);
var wait = del ? 50 : 100;
if (!del && n === w.length) { del = true; wait = 1400; } else if (del && n === 0) { del = false; i = (i + 1) % words.length; wait = 300; }
setTimeout(tick, wait);
})();
04. Terminal Command and Output
TypewriterTerminal
A command is typed at the prompt, then its output lines appear one by one, like a real terminal session. The typing uses steps() and the output lines fade in with delays that start after the typing ends.
No typing at all, just a block caret blinking after a finished heading, which gives a code-themed brand a hint of a terminal without making anyone wait to read. The caret is a decorative pseudo-element.
The line types a wrong word, pauses, deletes it and types the right one, a human touch for a hero or a cover letter site. A small script plays a list of type and delete steps; the finished sentence is in the HTML for screen readers and no-script visitors.
View code
<p class="ty6"><span class="sr">Websites that feel fast.</span><span class="v" aria-hidden="true">Websites that feel fast.</span></p>
var v = document.querySelector('.ty6 .v');
if (!matchMedia('(prefers-reduced-motion: reduce)').matches) {
var steps = [['t', 'Websites that feel slow'], ['w', 600], ['d', 4], ['t', 'fast.']], out = '', k = 0;
v.textContent = '';
(function run() {
var s = steps[k]; if (!s) return;
if (s[0] === 'w') { k++; setTimeout(run, s[1]); return; }
if (s[0] === 't') { if (s.n === undefined) s.n = 0; out += s[1][s.n++]; v.textContent = out; if (s.n >= s[1].length) k++; return setTimeout(run, 70); }
if (s[0] === 'd') { if (s.n === undefined) s.n = s[1]; out = out.slice(0, -1); v.textContent = out; if (--s.n <= 0) k++; return setTimeout(run, 60); }
})();
}
07. Typing Indicator Then Message
TypewriterChat
A chat bubble shows three bouncing dots while the other person types, then the message replaces them. The dots are aria-hidden with a visually hidden Typing label, and the final message lands in a polite live region so it is announced.
var w = document.querySelector('.ty7');
setTimeout(function () { w.innerHTML = '<div class="b">Hi! Your order shipped this morning.</div>'; }, 2600);
About these CSS Typewriter Effects
steps() and ch units
In a monospace font every character is exactly 1ch wide. Animate the width from 0 to the text's length in ch with steps(n), where n is the number of characters, and each step reveals one letter.
The caret is a border
A right border on the typed element makes a caret that moves with the text. Blink it with a separate step-end animation that turns the border colour transparent half the time.
Static text for screen readers
Changing text is read out again and again, or read half-typed. Keep the finished sentence in visually hidden text and hide the animated copy with aria-hidden.
Do not make people wait
Typing delays reading. Keep typed text short, start quickly and under prefers-reduced-motion show the finished text straight away.
Frequently asked questions
Can I type proportional fonts?
Not accurately with steps() and ch. Use the JavaScript demos, which add letters one by one, for any font.
How do I loop the CSS version?
Add infinite and alternate to the typing animation; it will type and then untype.
Is a typewriter effect accessible?
With a static copy for screen readers and a reduced-motion fallback, yes.