A CSS typewriter effect animates text appearing one character at a time, simulating the rhythm of a real typewriter or terminal prompt — the dominant pattern for hero headlines, landing-page intros, and code demos. These 14 hand-coded designs cover the full typewriter playbook — the canonical pure-CSS steps() + ch recipe, multi-line stagger, infinite word-swap loop, neon terminal, clip-path reveal, SVG handwriting, gradient sweep, variable-font weight morph, Matrix scramble decode, glitch-on-type, code editor syntax, and scroll-triggered reveal. Every demo uses scoped .tw-NN class names that never collide with your existing styles, honours prefers-reduced-motion, and ships under the MIT license.

14 unique typewriter effects 9 Pure CSS 5 CSS + JS 100% copy-paste ready Published
01 / 14
CSS Typewriter steps() Cursor
Pure CSS
CSS Typewriter steps() Cursor — preview
The canonical CSS-only typewriter: width animates from 0 to a fixed ch value using steps() timing, paired with a blinking border-right cursor — no JS at all.
02 / 14
CSS Typewriter Multiline Stagger
Pure CSS
CSS Typewriter Multiline Stagger — preview
Multiple lines reveal sequentially using staggered animation-delay on each row, creating a cascading terminal-output feel entirely in CSS.
03 / 14
CSS Typewriter Word Swap Loop
Pure CSS
CSS Typewriter Word Swap Loop — preview
A hero headline cycles through swappable highlight words using a single CSS keyframe that animates width and color on a looping overflow-hidden container.
04 / 14
CSS Typewriter Neon Terminal
Pure CSS
CSS Typewriter Neon Terminal — preview
A glowing neon CRT-style terminal with scanlines, phosphor bloom, and a stepped-width typewriter revealing a command prompt sequence — all in pure CSS.
05 / 14
CSS Typewriter clip-path Reveal
Pure CSS
CSS Typewriter clip-path Reveal — preview
Text is revealed character-by-character using an animated clip-path inset that travels left-to-right — giving a hard-edged paint-stroke reveal instead of the usual overflow trick.
06 / 14
CSS Typewriter SVG stroke-dashoffset
Pure CSS
CSS Typewriter SVG stroke-dashoffset — preview
SVG text paths are drawn stroke-first using an animated stroke-dashoffset, revealing each letter as a hand-lettered signature — a technique impossible with HTML alone.
07 / 14
CSS Typewriter Gradient Highlight Sweep
Pure CSS
CSS Typewriter Gradient Highlight Sweep — preview
Text is revealed by a travelling gradient mask that sweeps left-to-right, creating a spotlight-highlight typewriter where unread text sits invisible and highlighted text glows into view.
08 / 14
CSS Typewriter Variable Font Weight Morph
Pure CSS
CSS Typewriter Variable Font Weight Morph — preview
Each character of a variable font headline morphs from ultra-light to black weight as it "types in", using staggered font-variation-settings animations — no width tricks required.
09 / 14
CSS Typewriter Split Char Stagger
Pure CSS
CSS Typewriter Split Char Stagger — preview
Individual characters pop in sequentially using staggered translateY + opacity keyframes, creating a kinetic editorial type-in effect used in modern agency hero sections.
10 / 14
CSS Typewriter JS Character Injection
CSS + JS
CSS Typewriter JS Character Injection — preview
JavaScript injects characters one by one into the DOM at a configurable speed, enabling proportional fonts, dynamic strings, pause-on-hover, and click-to-restart — all styled with CSS.
11 / 14
CSS Typewriter Matrix Scramble Decode
CSS + JS
CSS Typewriter Matrix Scramble Decode — preview
Random characters scramble across the target string before each letter snaps to its final value — a hacker-movie decode effect powered by JS with CSS glow styling.
12 / 14
CSS Typewriter Glitch on Type
CSS + JS
CSS Typewriter Glitch on Type — preview
Each character causes a brief glitch distortion on the preceding text as it lands — RGB channel splitting and clip-path slice distortion fire per-keystroke via JS class toggling.
Advertisement
13 / 14
CSS Typewriter Code Editor Syntax
CSS + JS
CSS Typewriter Code Editor Syntax — preview
A realistic VS Code-style editor types out syntax-highlighted code line by line, with a live line-number gutter, blinking cursor, and language-aware coloring — all orchestrated by JS.
14 / 14
CSS Typewriter Scroll-Triggered Word Reveal
CSS + JS
CSS Typewriter Scroll-Triggered Word Reveal — preview
Words in a long-form paragraph reveal sequentially only when the element enters the viewport — IntersectionObserver triggers staggered CSS class additions for a scroll-activated typewriter effect.
FAQ

Frequently asked questions

What is a CSS typewriter effect and how does the pure-CSS recipe work?
A CSS typewriter effect animates text appearing one character at a time, simulating the rhythm of a real typewriter or terminal prompt. The canonical pure-CSS recipe (Demo #01) uses three CSS primitives layered together: (1) <code>overflow: hidden; white-space: nowrap</code> on the text element clips characters that haven't been revealed yet, (2) <code>@keyframes</code> animating <code>width: 0 → 22ch</code> using <code>steps(22)</code> timing — the <code>steps()</code> function produces discrete jumps rather than smooth interpolation, so each step reveals exactly one more character, (3) a second <code>border-right: 3px solid</code> animation toggling between an accent colour and <code>transparent</code> with <code>steps(2)</code> creates the hard on/off blink of a terminal cursor. Both animations run on the same element. <strong>Key insight</strong>: the <code>ch</code> unit is the width of the <code>0</code> character in the current font — combined with <code>steps()</code>, this gives pixel-perfect character-by-character snapping in any monospace font. Zero JavaScript, zero dependencies, ~30 lines of CSS total. The Animated steps() Cursor demo (#01) is the canonical reference everyone reaches for first.
Which typewriter pattern should I pick for my use case?
Decision rule by intent. <strong>Hero headline / above-the-fold</strong>: Demo #01 (steps() Cursor) for the classic terminal feel, Demo #08 (Variable Font Weight Morph) for a premium SaaS subtle effect, Demo #06 (SVG stroke-dashoffset) for handwritten editorial. <strong>Landing page subhead</strong>: Demo #03 (Word Swap Loop — Designer / Developer / Creator) for the rotating-noun pattern Stripe / Vercel / Linear use, Demo #02 (Multi-line Stagger) for 3-line opening copy. <strong>Code demo / docs / IDE replica</strong>: Demo #04 (Neon Terminal) for cyberpunk dev tools, Demo #13 (Code Editor Syntax) for tutorial sites and SaaS marketing where you show code typing itself. <strong>Brand / portfolio</strong>: Demo #07 (Gradient Highlight Sweep) for modern luxury, Demo #11 (Matrix Scramble Decode) for tech / Web3 / cyber brands, Demo #12 (Glitch on Type) for gaming / esports. <strong>Scroll storytelling</strong>: Demo #14 (Scroll-Triggered Word Reveal) types text as the user scrolls — perfect for long-read landing pages and case studies. <strong>Pure HTML/CSS sites (no JS allowed)</strong>: pick from demos 01–09 — all nine are zero-JavaScript. <strong>Marketing experiment / A-B test</strong>: Demo #03 (Word Swap) is the highest-converting hero pattern in 2024-2026 SaaS data — replacing static headlines with a rotating-noun typewriter lifted CTA click-through 8-15% across Optimizely / VWO case studies.
Pure CSS vs JavaScript typewriter — which should I use?
<strong>Pure CSS works for</strong>: single-string typewriters with a known character count (Demo #01), multi-line stagger with fixed text (#02), infinite word-swap loops with a small fixed word list (#03), <code>clip-path</code> reveals (#05), SVG <code>stroke-dashoffset</code> drawing (#06), gradient sweeps (#07), variable-font morphs (#08), per-character span stagger (#09). All nine pure-CSS demos in this collection achieve their effect without any JavaScript. <strong>JavaScript is required for</strong>: dynamic text that changes at runtime (user input, fetched content, randomized strings — Demo #10), Matrix-style scramble decode where intermediate characters are random glyphs that converge to the target (#11), glitch effects that need RGB-channel pseudo-elements driven by typing position (#12), syntax-highlighted code that needs token-by-token coloring as it types (#13), and scroll-driven typewriters that progress based on <code>IntersectionObserver</code> or <code>scroll-timeline</code> (#14). <strong>Modern alternative</strong> (Chrome 115+, Safari 26+, Firefox 134+): CSS scroll-driven animations via <code>animation-timeline: scroll()</code> let you do scroll-triggered typewriters in pure CSS too — Demo #14 includes a commented-out scroll-driven-animations version next to its <code>IntersectionObserver</code> implementation. Choose based on whether your text is fixed at build time (CSS) or generated at runtime (JS).
How is CSS typewriter compared to libraries like Typed.js, TypeIt.js, or react-typewriter-effect?
<strong>Typed.js</strong> (~9.5KB minified, ~250K weekly downloads): the most popular JS typewriter library, supports loops + multiple strings + custom cursors + smart backspacing. <strong>TypeIt.js</strong> (~13KB minified, ~150K weekly downloads): more configurable than Typed.js, supports rich HTML strings, function callbacks per character, fluent chaining API. <strong>typewriter-effect</strong> (npm, ~5KB): the most popular React wrapper for vanilla typewriter logic. <strong>react-typewriter-effect</strong>: similar, React-specific. <strong>What you gain by using a library</strong>: dynamic string lists, fluent API, backspace + delete behaviors, easier integration with React/Vue state, well-tested edge cases. <strong>What you LOSE</strong>: ~5-15KB of JavaScript bundle weight per page, an external dependency to update + audit for CVEs, slower First Contentful Paint and Largest Contentful Paint (the library has to download + parse + execute before the text appears). <strong>What this collection gives you</strong>: the same effect in 30 lines of CSS that ship inline with your HTML — zero bundle cost, zero npm dependency, zero CVE surface, faster FCP/LCP, no library hydration delay. For 90% of marketing use cases (one or two strings, no runtime mutation), the CSS approach wins on every Core Web Vitals dimension. Reserve Typed.js / TypeIt for app dashboards where the text legitimately needs runtime mutation.
Is the CSS typewriter accessible? What about screen readers and motion sensitivity?
Three accessibility concerns matter for typewriter effects. <strong>1. Motion sensitivity</strong>: ~35% of adults have some level of motion sensitivity — vestibular disorders, migraine triggers, ADHD-related visual processing. Typewriter animations are textbook motion that can trigger these. <strong>Fix</strong>: every demo in this collection wraps its <code>@keyframes</code> in <code>@media (prefers-reduced-motion: reduce) { animation: none; }</code> so users with that OS setting see the final text instantly, no typing animation. WCAG 2.3.3 (Animation from Interactions) explicitly recommends this. <strong>2. Screen readers</strong>: VoiceOver, NVDA, JAWS, and Narrator may either announce each character as it appears (annoying) or announce the empty element + final text (correct). Default behavior varies. <strong>Fix</strong>: set <code>aria-live='polite'</code> on the typewriter container so the final text is announced once after the animation completes, NOT per-character. For long strings, use <code>aria-label</code> with the full text + <code>aria-hidden='true'</code> on the visual typewriter so screen readers get the complete message immediately and sighted users get the animation. <strong>3. Cumulative Layout Shift (CLS)</strong>: a typewriter that animates text width can cause page reflow as characters appear — especially bad on hero sections that ship without the final string reserved. <strong>Fix</strong>: reserve the final character count with <code>width: 22ch</code> on the container (matching the steps() count), or wrap in a parent with explicit <code>min-width</code> matching the longest variant. Regulatory frameworks: <strong>EU EAA</strong> (June 2025), <strong>US Section 508</strong>, <strong>Canada ACA</strong>, <strong>UK Equality Act</strong> all require WCAG 2.2 AA compliance.
Tailwind / shadcn / MUI / Chakra typewriter — how do these compare?
None of <strong>Tailwind UI</strong>, <strong>shadcn/ui</strong>, <strong>Material UI</strong> / <strong>MUI</strong>, <strong>Chakra UI</strong>, <strong>Ant Design</strong>, <strong>Mantine</strong>, or <strong>HeadlessUI</strong> ship a first-class typewriter component — typewriters are typically built per-project using either: (a) the pure-CSS recipe from this collection (Demo #01), (b) a small custom React hook (Demo #10's pattern, ~20 lines), or (c) the Typed.js / TypeIt.js wrappers. <strong>Tailwind v3 / v4</strong>: you can compose the CSS pattern using arbitrary-value utilities — <code>w-[0ch] animate-[typing_2s_steps(22)_forwards] border-r-2 overflow-hidden whitespace-nowrap</code> — but you still need a custom <code>@keyframes typing</code> in your stylesheet because Tailwind doesn't ship width-to-22ch animation out of the box. Our <a href="/tools/css-to-tailwind-converter/">CSS to Tailwind converter</a> handles the conversion automatically. <strong>shadcn/ui</strong> (React + Radix Primitives): does not ship a typewriter; the community pattern is to wrap react-typewriter-effect or write a custom hook. <strong>Animation libraries</strong>: Framer Motion's <code>animate()</code> can drive a per-character variant; GSAP's SplitText plus <code>TextPlugin</code> can do glitch + scramble effects but adds ~30KB. The pure-CSS approach in this collection ships zero JavaScript for nine of the 14 demos — for typewriter-driven hero headlines on marketing pages, this is the lowest-overhead approach.
Why does my typewriter cause cumulative layout shift (CLS)?
CLS is one of three Core Web Vitals — Google measures it on every Lighthouse / PageSpeed Insights audit. Typewriters are a notorious cause of CLS spikes: the text container starts at <code>width: 0</code> and grows to fit the final string. If the parent layout reflows around it, every element below shifts position once per animation step. <strong>The fix</strong>: reserve the final character width <em>before</em> the animation starts. (1) For single-string typewriters: set <code>width: 22ch</code> on the parent that contains the typewriter, OR set <code>min-width: 22ch</code> on the typewriter element itself with the animation running on a child wrapper. (2) For word-swap loops with variable-length words: use the longest word's character count (e.g. if cycling through 'Designer / Developer / Creator', use <code>width: 9ch</code> matching 'Developer'). (3) For multiline typewriters: explicit <code>height</code> on the parent reserves vertical space. (4) For JS character-injection (Demo #10): pre-render the final string with <code>visibility: hidden</code> via a sibling element so the layout reserves space, then animate a visible sibling on top. <strong>Tools</strong>: Chrome DevTools Performance Insights (Layout Shift sections), Lighthouse, Web Vitals extension, Core Web Vitals report in Google Search Console. Demos in this collection are designed to avoid CLS by default — see the comment markers in each demo's CSS.
What's the difference between steps(), ease, and linear timing — and why does steps() work for typewriter?
CSS animations interpolate between keyframe values using a <strong>timing function</strong>. The default <code>linear</code> produces smooth continuous interpolation; <code>ease</code> / <code>ease-in</code> / <code>ease-out</code> produce smooth curves. <code>steps(N, end)</code> is different — it produces N <strong>discrete jumps</strong> rather than smooth interpolation. So animating <code>width: 0 → 22ch</code> with <code>steps(22)</code> produces 22 discrete width values (0ch, 1ch, 2ch, ... 22ch), each held for 1/22 of the total duration. The text container then jumps from showing 0 characters to 1, to 2, etc. — exactly like a typewriter. <strong>Common timing variants</strong>: <code>steps(N, start)</code> shows the first step at t=0 (immediate first character); <code>steps(N, end)</code> shows the first step at t=1/N (1-character delay before the first appears) — for typewriter you typically want <code>steps(N, end)</code> or just <code>steps(N)</code> which defaults to <code>end</code>. <strong>Pitfall</strong>: setting <code>steps(N)</code> where N != character count produces uneven character-reveal timing. Match steps to character count exactly. For variable-length strings (word swap, dynamic content), this means recomputing or using JS character injection (Demo #10). <strong>Modern alternative</strong>: <code>animation-timing-function: linear(...)</code> with an animation-timeline of scroll() lets you do scroll-driven character reveals via <code>steps()</code> too — see Demo #14.
Why does my typewriter look perfect in Chrome but break in Safari?
Two common Safari-specific traps. <strong>1. <code>ch</code> unit calculation</strong>: Safari calculates <code>1ch</code> against the OS-rendered <code>0</code> glyph metrics, which can differ subtly from Chrome's rendering — especially with system fonts (San Francisco on macOS vs Inter on Windows). The fix: use a monospace font where ALL characters have identical width (JetBrains Mono, IBM Plex Mono, Geist Mono, Fira Code). With a true monospace font, <code>ch</code> matches every character width exactly, eliminating the Safari/Chrome divergence. <strong>2. <code>steps()</code> + <code>animation-fill-mode: forwards</code> interaction</strong>: Safari < 17 has a known bug where <code>animation-fill-mode: forwards</code> combined with <code>steps()</code> sometimes drops the final keyframe state, leaving the typewriter at <code>width: 21ch</code> instead of <code>22ch</code>. The fix: add <code>animation-fill-mode: both</code> instead of <code>forwards</code> — <code>both</code> applies both <code>0%</code> and <code>100%</code> keyframes outside the animation range, which avoids the forwards-only edge case. Demos #01–#09 use <code>both</code> by default for this reason. <strong>3. Variable-font axis animation</strong> (Demo #08 — variable-font weight morph): Safari requires the variable font to be fully loaded BEFORE the animation starts, otherwise it falls back to the static weight. Fix: use <code>font-display: block</code> on the variable font's <code>@font-face</code> rule so the page waits for the font before painting — slight FCP cost in exchange for guaranteed rendering.
Are these typewriter effects free, accessible, and how do I attribute them?
Yes — all 14 typewriter effects are <strong>MIT licensed</strong> and free for personal and commercial use, including client projects, SaaS products, design systems, and open-source libraries. The MIT license requires only that you keep the copyright notice if you redistribute the source code as-is; in shipped production HTML / CSS that you've adapted, no visible attribution is needed. If you ship one as part of an open-source UI library or component kit, a one-line credit pointing to https://codefronts.com is appreciated but not legally required. <strong>Accessibility</strong>: every demo honours <code>prefers-reduced-motion: reduce</code> (animations fall back to instantly-displayed final text), uses semantic HTML, and is designed to work with <code>aria-live</code> regions for screen readers — see FAQ #5 for the full a11y pattern. Verify your specific use case with <strong>axe DevTools</strong>, <strong>Lighthouse</strong>, <strong>WAVE</strong>, or <strong>WebAIM contrast checker</strong> before shipping to EU EAA / US Section 508 / Canada ACA / UK Equality Act audits — the demos are AA-compliant by default but layout-context matters.

Related collections

15 CSS Background Animations preview

15 CSS Background Animations

15

15 hand-coded CSS background animations with live demos — infinite shifting gradient, floating particle bubbles, parallax starry night, clickable cyberpunk ripple, sliding geometric grid, SVG wave overlays, glassmorphism orbs, aurora borealis ribbons, matrix digital rain, mesh gradient blobs, falling snow, morphing blob, retro synthwave 3D grid, infinite scrolling diagonal marquee, comic-book halftone dots. 100% Pure CSS, no JavaScript, no canvas, no particles.js. prefers-reduced-motion respected, scoped class names, MIT-licensed.

css background animation animated gradient background css css floating particles Responsive
27 CSS Button Hover Effects preview

27 CSS Button Hover Effects

27

27 hand-coded CSS button hover effects — 3D press, neon glow, gradient slide, border draw, liquid fill, ripple, glitch text, and kinetic flips. Every demo is pure CSS (no JavaScript, no framework), tuned for 60fps with transform and opacity, and respects prefers-reduced-motion out of the box.

css buttons button hover button hover effects Responsive
33 CSS Card Hover Effects preview

33 CSS Card Hover Effects

33

33 hand-coded CSS card hover effects with live demos — multi-axis 3D tilt with parallax, glowing gradient glassmorphic border, image zoom with content slide-up, front-to-back 3D flip, sibling de-emphasis with :has(), minimalist elevation, plus 27 more (elastic lift, conic-gradient border, holographic foil, neon sign, glitch RGB split, magnetic float, blueprint reveal, aurora drift and more). 26 pure CSS + 7 with a small vanilla JS snippet for cursor tracking. prefers-reduced-motion respected, scoped class names, MIT-licensed.

css card hover effect css card hover animation card hover effect pure css Responsive

Search CodeFronts

Loading…