You've seen it in Instagram bios, Discord names and game nicknames: ๐๐จ๐ฅ๐, ๐ช๐ต๐ข๐ญ๐ช๐ค, ๐๐ธ๐๐พ๐ ๐, ๐ฃ๐ฏ๐๐จ๐ฑ๐ฒ๐ฏ, โโโกโโโโ, ๏ฝ๏ฝ๏ฝ๏ฝ๏ฝ๏ฝ๏ฝ๏ฝ๏ฝ and tฬทฬขอhฬถฬคอiฬตออsฬธฬฑฬพ kind of chaos, all pasted into fields that only accept plain text.
None of that is a font. No CSS, no rich text, no <b> tag. Every one of those glyphs is its own Unicode code point, and the "fancy text generators" all over the web are mostly lookup tables. This post goes through the blocks those characters come from, why the alphabets have strange gaps, and what they cost you in accessibility and searchability.
Fonts vs. characters
Normally "bold" is presentation. The character A (U+0041) stays the same, and your font or CSS decides how heavy it looks. Copy it somewhere else and the boldness is gone.
Fancy text works the other way. ๐ is U+1D400 MATHEMATICAL BOLD CAPITAL A, a separate character from A. Because the style is part of the character, it survives copy-paste into any plain-text field, provided the reader's device has a font that can draw it.
That one fact explains both why these characters are useful and most of the trouble they cause.
1. Mathematical Alphanumeric Symbols (U+1D400โU+1D7FF)
Most fancy text comes from this block. It was added in Unicode 3.1 (2001), mainly for mathematicians, because in math notation the style of a letter carries meaning. A bold x might be a vector, a fraktur ๐ค a Lie algebra, and a double-struck โ the real numbers. Those distinctions need to survive in plain text, so Unicode encoded them as separate characters.
The block contains full Latin alphabets (and some Greek letters and digits) in styles such as:
| Style | Example | Starts at (capital A) |
|---|---|---|
| Bold | ๐๐๐ ๐๐๐ | U+1D400 |
| Italic | ๐ด๐ต๐ถ ๐๐๐ | U+1D434 |
| Bold italic | ๐จ๐ฉ๐ช | U+1D468 |
| Script | ๐๐๐ | U+1D49C |
| Bold script | ๐๐๐ | U+1D4D0 |
| Fraktur | ๐๐ ๐ | U+1D504 |
| Double-struck | ๐ธ๐น๐ป | U+1D538 |
| Bold fraktur | ๐ฌ๐ญ๐ฎ | U+1D56C |
| Sans-serif (+ bold/italic) | ๐ ๐ ๐ ๐ผ | U+1D5A0โฆ |
| Monospace | ๐ฐ๐ฑ๐ฒ | U+1D670 |
There are also bold, double-struck, sans-serif and monospace digits (๐๐๐, ๐๐๐, ๐ถ๐ท๐ธ) near the end of the block, starting at U+1D7CE.
The holes, and why they exist
Try generating italic "hello" by adding a fixed offset and you'll hit a problem: U+1D455, where italic small h should be, is unassigned. The same goes for several letters in the script, fraktur and double-struck alphabets.
The reason is history. Some of these letters were already in Unicode before 2001, in the Letterlike Symbols block (U+2100โU+214F), because they were common symbols:
-
โU+210E PLANCK CONSTANT, which serves as the italic small h -
โฌU+212C SCRIPT CAPITAL B,โฐ,โฑ,โ,โ,โ,โณ,โ, plus smallโฏ,โ,โด -
โญU+212D BLACK-LETTER CAPITAL C,โ,โ,โ,โจ -
โU+2102 DOUBLE-STRUCK CAPITAL C,โ,โ,โ,โ,โ,โค
Unicode doesn't encode the same character twice, so the matching slots in the math block were left as reserved holes. Any generator that hasn't special-cased them will output missing characters for words like "Chess" in double-struck.
2. Enclosed Alphanumerics (U+2460โU+24FF) and the Supplement (U+1F100โU+1F1FF)
The "bubble" letters come from Enclosed Alphanumerics:
- circled:
โถU+24B6 โฆโU+24D0 โฆ - parenthesized:
โโโ - circled and parenthesized numbers:
โ โกโข,โดโตโถ
Many of these came into Unicode for compatibility with older East Asian character sets, where enclosed numbers and letters were common in lists and labels.
The Enclosed Alphanumeric Supplement adds heavier variants:
- negative circled:
๐ U+1F150 โฆ - squared:
๐ฐ๐ฑ๐ฒ - negative squared:
๐ ฐU+1F170 โฆ, the source of the ๐ ฐ๐ ฑ "blood type" glyphs. With emoji presentation these display as red emoji on many platforms. - regional indicator symbols (U+1F1E6โU+1F1FF), which aren't decorative letters. In pairs they form flags: ๐ฒ + ๐ฝ = ๐ฒ๐ฝ.
3. Halfwidth and Fullwidth Forms (U+FF00โU+FFEF)
๏ฝ๏ฝ๏ฝ๏ฝ๏ฝ๏ฝ๏ฝ๏ฝ๏ฝ
๏ฝ๏ฝ
๏ฝ๏ฝ๏ฝ๏ฝ
๏ฝ๏ฝ๏ฝ text uses fullwidth Latin letters such as ๏ผก U+FF21 and ๏ฝ U+FF41.
These come from CJK computing. In Chinese, Japanese and Korean text, characters sit on a square grid, and older East Asian encodings included "wide" versions of Latin letters and digits so they would fill one full cell and line up with ideographs. Halfwidth katakana (๏ฝฑ๏ฝฒ๏ฝณ) are the reverse case: narrow forms from early systems with limited display space. Unicode kept both for round-trip compatibility with those legacy encodings.
Out of context, the extra width reads as a "vaporwave" look.
4. Combining characters, Zalgo, underline and strikethrough
A combining character has no width of its own. It attaches to the character before it. The main range is Combining Diacritical Marks, U+0300โU+036F: e + U+0301 โ รฉ.
Unicode doesn't limit how many marks you can stack on one base character. Stack dozens above and below and you get Zalgo text:
Hฬตฬกฬฬฬชฬeฬธฬขอฬ ฬดฬฐฬcฬทฬบฬฬoฬถฬงอmฬตฬฬeฬธฬซอsฬทฬชฬฬ
Renderers try to stack the marks, run out of room, and draw them over neighboring lines.
The same mechanism gives you underline and strikethrough in plain text:
-
U+0332COMBINING LOW LINE after each letter: uฬฒnฬฒdฬฒeฬฒrฬฒlฬฒiฬฒnฬฒeฬฒ -
U+0336COMBINING LONG STROKE OVERLAY: sฬถtฬถrฬถiฬถkฬถeฬถ -
U+0335(short stroke) andU+0338(solidus overlay) give variations such as sฬธlฬธaฬธsฬธhฬธ
How cleanly these join depends entirely on the font and the text renderer.
5. Small caps, superscripts and upside-down text
Unicode has no small-caps alphabet. Generators borrow letters from linguistics instead:
-
IPA (U+0250โU+02AF) has
ส ษข ษช ส ส ษด ส ส, which phoneticians use as real symbols. -
Phonetic Extensions (U+1D00โU+1D7F) adds
แดU+1D00,แด แด แด แด แด แด แด แด แด แด แด แดก แดข, and modifier letters such asแดฌ แดฎ แดฐ.
The result, ๊ฑแดแดสส แดแดแด๊ฑ, is assembled from several blocks, which is why some letters look slightly off.
Superscript text (หขแตแตแตสณหขแถสณโฑแตแต) works the same way, combining modifier letters from Spacing Modifier Letters, Phonetic Extensions and Superscripts and Subscripts. A few letters have no superscript form at all; there is no dedicated superscript small q, for example. Generators either substitute something similar or leave the letter as it is.
Upside-down text (สxวส uสop-วpแดsdn) combines character reversal with a lookup table of look-alikes: ษ U+0250 LATIN SMALL LETTER TURNED A, ว, ษฅ, ษฏ, ส, plus punctuation such as ยฟ and ยก. These are mostly real IPA letters used for their shape, not true rotated copies.
6. A tiny generator in JavaScript
Since the bold block has no holes, a bold generator is just arithmetic on code points:
const toMathBold = (s) =>
[...s].map((ch) => {
const c = ch.codePointAt(0);
if (c >= 0x41 && c <= 0x5a) return String.fromCodePoint(0x1d400 + (c - 0x41)); // AโZ
if (c >= 0x61 && c <= 0x7a) return String.fromCodePoint(0x1d41a + (c - 0x61)); // aโz
if (c >= 0x30 && c <= 0x39) return String.fromCodePoint(0x1d7ce + (c - 0x30)); // 0โ9
return ch;
}).join("");
const out = toMathBold("Hello World 2026");
console.log(out); // ๐๐๐ฅ๐ฅ๐จ ๐๐จ๐ซ๐ฅ๐ ๐๐๐๐
console.log(out.length, [...out].length); // 30 16
console.log(out.normalize("NFKC")); // Hello World 2026
Three things to notice in the output (I ran this on Node 22):
-
out.lengthis 30, not 16. These characters are outside the Basic Multilingual Plane, so each one takes a UTF-16 surrogate pair. UsecodePointAt,String.fromCodePointand[...str], notcharCodeAtorsplit(""), or you'll split characters in half. It also matters for character limits: a platform counting UTF-16 units sees a 16-character name as 30. - NFKC normalization turns it back into "Hello World 2026". These characters have compatibility decompositions to plain letters. That's useful for search and moderation pipelines, and it shows that Unicode itself treats them as styled versions of ordinary letters.
- For italic, script, fraktur or double-struck, you need an exception map for the Letterlike Symbols holes (
h โ โ,C โ โand so on). Otherwise you'll output unassigned code points.
7. Caveats: when not to use fancy text
These characters are fun, but they have real costs, and you should know about them before putting them in front of users.
Accessibility. Screen readers handle math alphanumerics inconsistently. Depending on the reader and its settings, ๐๐๐ฅ๐ฅ๐จ may be read as "mathematical bold capital H, mathematical bold small eโฆ", spelled out letter by letter, or skipped entirely. Zalgo and upside-down text are worse. If someone who uses a screen reader needs to understand it, don't style it this way. At most, style a word or two and keep the important information in plain text.
Search and indexing. To a naive search, ๐๐จ๐๐๐๐ and coffee are different strings. Some systems apply NFKC or similar folding and some don't, so a fancy-text username or bio may not show up when people search for the plain word. Don't put your brand name, handle or keywords only in fancy letters.
Platform support. Most fields on Instagram, TikTok, WhatsApp, Discord and X accept these characters because they're just Unicode. Rendering depends on the viewer's fonts, and older Android phones in particular may show โก boxes. Games are stricter. Free Fire nicknames, for example, are a popular use, but games validate names against their own character rules and length limits, which can change, so test on the platform before you commit. Display names and handles also usually follow different rules.
Copy-paste and data. The style travels with the text, so it ends up in places you didn't intend: spreadsheets, CSV exports, CRM fields, grep failures. For developers, that also means:
- validate and normalize (NFKC) usernames to prevent look-alike impersonation (๐๐๐ฆ๐ข๐ง vs admin)
- count graphemes or code points, not UTF-16 units, when enforcing limits
- strip or limit combining marks if Zalgo would break your layout
Never use them for passwords, email addresses, URLs, legal or medical text, or anything someone needs to type back.
Try it
To see all of these blocks side by side without writing your own lookup tables, try Letras Bonitasz. It's a free Spanish-language generator: type a word and it shows the math, enclosed, fullwidth, small-caps and upside-down styles, and you can copy whichever you want. It has a dedicated Zalgo text page for testing how your app handles stacked combining marks, which works well as test input for UI layouts.
A fun exercise: paste its output into your own app's username field, run it through normalize("NFKC"), and see what your validation, search and length checks do with it.
Further reading: Wikipedia's articles on Mathematical Alphanumeric Symbols, Enclosed Alphanumerics, Halfwidth and Fullwidth Forms, Combining character and Zalgo text, and the official charts at unicode.org/charts.
Top comments (0)