Unicode, Fonts & Fancy TextJanuary 15, 2025

What Is Zalgo Text? The Glitch Aesthetic Explained

Zalgo text — the dripping, glitchy letters you see in horror memes — is built from Unicode combining marks. Here's how it works and why it matters.

By Muhammad Umair · Founder & Editor at TextKit

What Is Zalgo Text? The Glitch Aesthetic Explained

You've seen it. The dripping, corrupted-looking text that haunts Reddit creepypasta, the comment sections of creepypasta YouTube channels, and the bios of people who want you to know they're a little unwell:

H̷e̵l̷l̸o̴ ̷w̵o̷r̸l̵d̷ ̶i̵s̴ ̷c̷o̸m̸i̸n̵g̸ ̷f̷o̵r̷ ̴y̸o̵u̷

That's Zalgo text. It looks like a font corruption, a rendering bug, or something that escaped from a haunted printer. It is none of those things. It's a perfectly valid Unicode string — and once you understand how it's built, you'll see it everywhere from horror aesthetic to webcomics to deliberately unreadable Discord handles.

This article explains what Zalgo actually is, where it came from, how the trick works at the code-point level, what the accessibility cost is, and how to generate (or de-generate) it yourself.

What Zalgo actually is

Zalgo text is regular ASCII letters with dozens of Unicode combining diacritical marks stacked on top of, behind, and below them. That's the whole trick. There's no font, no corruption, no rendering bug. The marks are real Unicode characters that rendering engines are required to draw — and when you stack enough of them, they overflow their line and bleed into the surrounding text.

A "combining character" is a code point that, instead of standing alone, attaches to the preceding base character. The combining acute accent U+0301 (◌́) is a classic example: place it after an e and you get é. The base letter and the combining mark together form a single grapheme cluster — one visual "letter" that just happens to be made of multiple code points.

The combining marks block is U+0300U+036F (Combining Diacritical Marks), and there are several related blocks: U+1AB0U+1AFF (Combining Diacritical Marks Extended), U+1DC0U+1DFF (Combining Diacritical Marks Supplement), and U+20D0U+20FF (Combining Diacritical Marks for Symbols). Together they total hundreds of marks that can attach to a base character.

Unicode places no limit on how many combining marks can attach to a single base character. This was a deliberate design choice: a linguist encoding a complex tonal language might need three or four marks on one letter. But the spec doesn't say "up to four" — it says "as many as you want." And that's the loophole Zalgo exploits.

A worked example

Let's build a single Zalgo character by hand. Take the letter H (U+0048). Now add, in order:

  • U+0315 — Combining comma above right (looks like a tick)
  • U+0310 — Combining candrabindu
  • U+0337 — Combining short solidus overlay (a slash)
  • U+0338 — Combining long solidus overlay (a longer slash)
  • U+0324 — Combining diaeresis below
  • U+0322 — Combining hook below
  • U+033B — Combining square below
  • U+032E — Combining breve below
  • U+0334 — Combining tilde overlay
  • U+0349 — Combining horn

Paste them in sequence after the H and you get:

H̸̷̢̤̮͉̐̕͞

That's 11 code points rendering as a single horrifying glyph. The renderer has no choice — Unicode says "draw all of these attached to the H," so it does, even if the result overflows the line, overlaps the next character, or extends below the baseline. The glitchiness is emergent behavior, not a bug.

A full Zalgo sentence repeats this for every character. A medium-intensity Zalgo generator might add 5–15 marks per letter; a maximalist one can attach 50+ marks per character, producing text that takes a noticeable fraction of a second to render and looks like this:

̷H̸e̵l̷l̸o̴ ̷w̵o̷r̸l̵d̷ ̶i̵s̴ ̷c̷o̸m̸i̸n̵g̸ ̷f̷o̵r̷ ̴y̸o̵u̷

Multiply that across a paragraph and you've got a wall of corrupted text — but every byte of it is valid Unicode.

Where Zalgo came from

The aesthetic is older than the name. Stacked diacritics have appeared in academic linguistics papers for decades. But the meme — the deliberate use of stacking as a horror / glitch aesthetic — crystallized around 2006–2009 on Something Awful and 4chan, attached to a recurring character named "Zalgo." Zalgo was imagined as an eldritch entity ("HE COMES") whose presence corrupted reality, and the corrupted text was the visual signature. The original Zalgo generator, a single HTML file by an anonymous author, went viral around 2009 and is still hosted in various mirrors.

The aesthetic spread to:

  • Creepypasta and SCP Foundation entries — Zalgo-style text is a standard visual shorthand for "this thing is wrong / infected / breaking down."
  • Webcomics — Homestuck famously used it; Problem Sleuth and other MS Paint Adventures titles did too.
  • Liminal space / backrooms content — corrupted text signals that something is off.
  • Glitchcore and weirdcore music — album art and track titles.
  • Twitter handles and Discord names of users in certain subcultures.
  • Meme captions where the joke is the text itself falling apart.

It's a kind of folk typography: a way for non-designers to produce a specific emotional effect — dread, corruption, wrongness — using only characters that exist on every computer.

How Zalgo generators actually work

A typical Zalgo generator does something like this:

  1. Take the input string.
  2. For each character, optionally decide whether to "Zalgo" it (some skip spaces; some corrupt everything).
  3. For each chosen base character, randomly select N marks from a hand-curated set of "top" (above), "middle" (overlay), and "bottom" (below) combining marks.
  4. Concatenate base + marks + next base + marks + ...
  5. Output the result.

The "mini" / "normal" / "max" intensity settings just change N. A small Zalgo (N=2–3) is barely noticeable; a max Zalgo (N=20+) looks like the text is melting.

A minimal Python implementation:

import random

TOP = "\u030d\u030e\u0304\u0305\u033f\u0311\u0310\u0307\u0308\u030a"
MID = "\u0315\u031b\u0340\u0341\u031c\u033d\u033c\u0334\u0313\u0318"
BOT = "\u0316\u0317\u0319\u031a\u033b\u033a\u033e\u0323\u0324\u0325\u0326\u0329\u032a\u032b\u032c\u032d\u032e\u0327\u0328\u0333\u0339\u0338"

def zalgo(text, intensity=5):
    out = []
    for ch in text:
        if ch == " ":
            out.append(ch)
            continue
        n = random.randint(1, intensity)
        marks = "".join(random.choice(TOP + MID + BOT) for _ in range(n))
        out.append(ch + marks)
    return "".join(out)

print(zalgo("hello world", intensity=8))

Run it and you'll get something like h̠̣̝̄̌ḛ̡̏l̛̬̕l̤̃̌ǒ̢ ͔̈ẁọ̥̊r͍̄l͓̣̰̄d̛̗̄. Each invocation is random, so no two runs match — which is part of the aesthetic.

Why some marks work better than others

Not every combining mark renders well for Zalgo. Some are designed to be invisible unless they have something to combine with (in which case they sit on top of the next character). Some renderers ignore certain marks. The "good" Zalgo marks are the ones that produce visible artifacts at any position: dots, slashes, ticks, hooks, breve shapes, rings, and (most importantly) the Combining Grapheme Joiner U+034F — which is invisible but is sometimes used to defeat text processing that would otherwise normalize the marks away.

A well-curated Zalgo generator is essentially a hand-tuned list of marks that consistently render visibly across major font stacks. The list above is a reasonable starting set.

The accessibility cost

Zalgo text is, by design, hostile to accessibility. Here's the breakdown:

Screen readers

A screen reader reads a grapheme cluster as a sequence of code point names. H̸̷̢̤̮͉̐̕͞ is announced as something like "H, combining comma above right, combining candrabindu, combining long solidus overlay, combining short solidus overlay, combining diaeresis below, combining ring below, combining palatal hook below, combining tilde overlay, combining horn." For a full Zalgo sentence, that's hundreds of mark names back-to-back. Unusable.

Even worse: some screen readers, faced with a long run of combining marks, will simply stop reading or skip the whole cluster. So a Zalgo sentence might be read as "H [silence] e [silence] l [silence]…" — which gives a blind user the false impression that the text is just a sequence of single letters.

Cognitive load

For sighted readers with dyslexia or related conditions, Zalgo is significantly harder to parse than normal text. The marks obscure letter shapes, and the unpredictable visual noise can trigger headaches or visual fatigue in longer doses.

Rendering performance

Each combining mark is a glyph lookup and a positioning computation. A 1,000-character Zalgo paragraph with 20 marks per character is 20,000 glyph operations. On modern hardware this is fine, but on low-end devices it can cause visible lag when scrolling.

Search

Zalgo text is essentially unsearchable. The base characters are still there (sort of — they're interspersed with marks), but no search engine normalizes combining marks out of the query, so a search for "hello" will not match h̠̣̄̌ḛ̡̏l̛̬̕l̤̃̌ǒ̢. If you're using Zalgo in a way that matters for discoverability, you're hiding yourself.

Copy-paste

Zalgo text copies fine (it's just Unicode), but pasting it into a system that has a character limit can blow the budget instantly. A 50-character bio limit might be eaten by a single Zalgo word. Some platforms (notably Discord, in certain channels) auto-strip combining marks beyond a threshold.

Should you use Zalgo?

Like any aesthetic tool, Zalgo has appropriate and inappropriate uses.

Reasonable uses:

  • Horror / creepypasta fiction and ARG content.
  • Username flair in informal spaces where the audience expects it.
  • Decorative headers in personal blogs or zines.
  • Art projects where the unreadability is the point.
  • Memes.

Unreasonable uses:

  • Body text on any informational page.
  • Anything a screen reader is expected to parse.
  • Job applications, professional bios, customer-facing communication.
  • Long-form fiction where the reader needs to actually read it.
  • Anything in a UI that should remain clickable or selectable.

A good rule: if the reader needs to actually read it, don't Zalgo it. Zalgo works as atmosphere, not as content.

De-Zalgo: cleaning up corrupted text

If you receive Zalgo text and want the underlying plain text back, the fix is conceptually simple: strip every combining mark. In practice, you iterate over the string's code points and discard anything in the combining-mark ranges (or, more robustly, anything with Unicode category Mn — non-spacing mark — or Me — enclosing mark).

In Python:

import unicodedata

def dezalgo(text):
    return "".join(
        ch for ch in text
        if unicodedata.category(ch) not in ("Mn", "Me")
    )

print(dezalgo("H̸̷̢̤̮͉̐̕͞e̖̦̹͎̟l̜l̝o̮̤"))
# → Hello

JavaScript:

function dezalgo(str) {
  return Array.from(str).filter(ch => {
    // Strip the common combining ranges
    const cp = ch.codePointAt(0);
    return !(
      (cp >= 0x0300 && cp <= 0x036F) ||
      (cp >= 0x1AB0 && cp <= 0x1AFF) ||
      (cp >= 0x1DC0 && cp <= 0x1DFF) ||
      (cp >= 0x20D0 && cp <= 0x20FF) ||
      (cp >= 0xFE20 && cp <= 0xFE2F)
    );
  }).join("");
}

This recovers the base letters. It won't recover legibility if the original used unusual lookalike substitutions (Zalgo is sometimes mixed with other Unicode tricks), but for the standard "ASCII + combining marks" form, this works perfectly.

Zalgo and the wider Unicode-design debate

Zalgo is the most famous example of what Unicode engineers call the "combining marks stacking" problem — the fact that the spec permits grapheme clusters of arbitrary length. It's not the only one. Others include:

  • Tonal languages in West Africa that legitimately stack 4–6 marks on one base letter, sometimes rendering as a small "mountain" of dots and lines that overlaps with the next letter. Linguists have asked Unicode for years to consider whether to limit stacking; so far, the answer has been no.
  • Emoji sequences like the family 👨‍👩‍👧‍👦 (joined by Zero Width Joiners, U+200D) which can extend grapheme clusters to 7+ code points and break naive string length calculations.
  • Flag emoji (🇯🇵), which is two regional indicator letters joined into one glyph — and which renders as two letters on systems without flag support.

The Unicode Consortium's position is essentially: the spec describes what's allowed, and applications decide what to render. A renderer is technically permitted to cap the number of marks it draws per character (and some do), but most honor the spec faithfully, which is why Zalgo works at all. The price of supporting real-world linguistic complexity is that you also support the abuse cases.

The bottom line

Zalgo text is built from three ideas:

  1. Unicode lets you attach combining marks to base characters.
  2. There's no limit on how many marks you can stack.
  3. Renderers will draw them all, even when the result overflows the line.

That's the entire trick. The aesthetic — dripping, corrupted, glitchy — emerges from those three facts plus a curated list of marks that render visibly across font stacks.

It's a folk art form: a way of using a system designed for linguistics to express a feeling it was never meant to express. And like any folk art, it has its proper place. Use it where the unreadability serves the work; avoid it where readers (sighted or not) actually need to read what you wrote.

If you're curious about the broader landscape of Unicode-based text tricks — fancy fonts, bubble letters, upside-down text — read our Unicode beginner's guide and our fancy fonts deep dive.

Last reviewed: January 15, 2025. This article is part of TextKit's original content library. Spotted an error or have feedback? Tell us.