Text✨ Premium

Typewriter Glitch

Character-by-character typewriter with random glitch bursts — character swaps and flickers that self-correct on each keystroke, looping endlessly.

JSTypewriterGlitch

You'll get access to the interactive demo with a free account.

This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Text has 56 effects, including 4 free. Explore the category →

3 usage examples

Terminal hero — CLI tool landing page — Typewriter Glitch example 1

① Terminal hero — CLI tool landing page

WhenA landing page for a developer tool, a technical SaaS, or a product with a terminal/retro-futuristic aesthetic.
WhyThe effect types the product promise letter by letter; glitch interruptions reinforce the 'machine' identity without weighing down the page — no canvas, no framework.
Settingsdata-text="BUILD. DEPLOY. REPEAT_", font-size 3rem, brand primary color instead of white, restart pause at 3,000 ms.
Boot screen — Retro system dashboard — Typewriter Glitch example 2

② Boot screen — Retro system dashboard

WhenA monitoring dashboard, a DevOps tool, or a terminal-style game displays a boot sequence or a live status message.
WhyLetter-by-letter typing mimics a real terminal; glitch bursts create the impression of an unstable signal without heavy JS — ideal for short messages like 'CONNECTING…' or 'SCANNING_'.
Settingsdata-text="CONNECTING…_", font-size 1.1rem, green color (#00ff88), glitch probability raised to 40% (Math.random() < 0.40).
Intercepted message — Interactive fiction or ARG — Typewriter Glitch example 3

③ Intercepted message — Interactive fiction or ARG

WhenA narrative game, interactive fiction, or ARG presents a message from an unknown source as a corrupted incoming transmission.
WhyThe glitch is no longer decorative: it becomes a narrative mechanic. Each self-correction simulates real-time decryption — the decoding register is justified by the effect itself, not just layered over it.
Settingsdata-text="PROTOCOL ALPHA COMPROMISED_", font-size 1.1rem, cyan color (#00e5ff), glitch probability raised to 45% (Math.random() < 0.45), corruption rate at 50% (Math.random() < 0.50), restart pause at 4,000 ms.

How it works

The text from the data-text attribute is typed character by character via chained setTimeout calls (80–180 ms random delay per keystroke). A blinking cursor (|) is managed independently by a setInterval at 530 ms that appends or removes the | from the element's textContent — both timers coexist without blocking each other.

On each keystroke, a 25% probability triggers a glitch burst: 3 to 6 frames spaced 50 ms apart scan the already-typed characters and randomly replace 35% of them with a symbol from the set !@#$%^&*()_+-=[]{}|;:<>?/~`0123456789. During the burst, the element's opacity flickers between 1 and 0.6 to simulate a video-signal flicker. At the end of the burst, the correct text is restored before advancing to the next letter.

Once the full text is typed, the animation pauses for 2,000 ms then restarts from index 0 — infinite loop. The whole thing is a vanilla IIFE: zero dependencies, zero canvas, zero CSS animations. Courier New is a system font — no network request needed.

Accessibility

  • No prefers-reduced-motion support in the shipped code: the animation runs regardless of OS setting. For motion-sensitive users, manually add if (matchMedia('(prefers-reduced-motion: reduce)').matches) return; at the top of the IIFE.
  • The element exposes its content via textContent — readable by screen readers, but rapid mutations during glitch bursts may trigger spurious announcements. Wrap in a <span aria-live="off"> to suppress them.
  • High contrast: white text (#fff) on a dark background (#0a0a0f) — ratio ≈ 21:1, WCAG AAA.
  • No keyboard interaction or focusable area: purely decorative effect. If used as a main heading, add an aria-label with the final static text.
  • The Courier New font is a ubiquitous system font — no FOUT, no network request.

Browser compatibility

Uses only textContent, setInterval, and setTimeout — no Canvas, no CSS animations, no recent APIs required.

Chrome 80+✓ Full
Firefox 78+✓ Full
Safari 13+✓ Full
Edge 80+✓ Full
Mobile iOS✓ Full
Android Chrome✓ Full

Without JavaScript, the element shows the initial <code>|</code> character (static DOM content) — the page stays readable, no fatal error.

The code

HTML structure to paste into your page (CSS + JS available with a premium account):

index.html — structure
<div class="kt-text kt-typewriter-glitch" id="typewriter1" data-text="YOUR TEXT_">|</div>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
data-text "TYPEWRITER_" Text to type — edit this HTML attribute to change the content without touching the JS.
var fullText (JS) "TYPEWRITER_" JS fallback when data-text is absent. Set this variable directly in the code.
setTimeout(80 + Math.random() * 100) (JS) 80–180 ms/char Typing speed. Replace with setTimeout(typeNext, 120) for a constant pace, or drop to 40 ms for a fast-render feel.
Math.random() < 0.25 (JS) 25% Per-keystroke glitch burst trigger probability. Raise to 0.50 for a chaotic effect, lower to 0.05 for a nearly clean render.
Math.random() < 0.35 (JS) 35% Character corruption rate during a burst. 0.10 = subtle glitch, 0.70 = nearly unreadable text.
setInterval(530) (JS) 530 ms Cursor blink speed. 300 ms = fast, 800 ms = slow. Change the value inside setInterval.
.kt-text font-size (CSS) 2.2rem Text size. Increase to 4–6rem for full-screen hero usage.
.kt-typewriter-glitch font-family (CSS) "Courier New", monospace Font face. Swap to Georgia, Arial, or a locally-loaded font to change the aesthetic.
setTimeout(…, 2000) (JS — loop) 2,000 ms Pause before restarting after the full text is typed. Increase to 5,000 ms for a long hold, or remove the call to stop after one pass.

FAQ

The IIFE targets a single getElementById. To support multiple instances, extract the logic into a parameterized function: function initTypewriter(id, text) { var el = document.getElementById(id); var fullText = text; … typeNext(); } then call it once per element with its id and text.
No, it loops indefinitely. For a single pass, remove the setTimeout(function() { idx = 0; typeNext(); }, 2000) in the final branch of typeNext() — the animation then stops on the blinking cursor once the full text is displayed.
Remove the cursor setInterval and replace border-right: 3px solid rgba(255,255,255,.7) with border-right: none in .kt-typewriter-glitch. In typeNext(), also remove the (cursorVisible ? '|' : '') concatenations.