DEV Community

Picute
Picute

Posted on

Those "fancy fonts" in Instagram and TikTok bios aren't fonts โ€” they're Unicode

You paste ๐“ฑ๐“ฎ๐“ต๐“ต๐“ธ into an Instagram bio and it just works โ€” no app, no image, no CSS. Copy it back out and it survives. That's the tell that it was never a font at all. It's Unicode.

Here's what's actually happening, why it travels everywhere, and the three gotchas worth knowing if you ever build or debug one of these.

A "font" changes how a glyph is drawn. This changes the character.

A real font โ€” bold, italic, a script typeface โ€” is a rendering instruction layered on top of the same underlying character. The letter h stays U+0068 LATIN SMALL LETTER H; the font just paints it differently. Strip the styling and you still have h.

Fancy text works the other way around. ๐“ฑ is not an h wearing a costume โ€” it's a different code point: U+1D4F1 MATHEMATICAL SCRIPT SMALL H. Unicode shipped whole parallel alphabets, mostly for mathematicians who need a "script H" and a "bold H" to mean different things in one equation. Generators just borrow those alphabets for aesthetics.

The blocks you see most often:

  • Mathematical Alphanumeric Symbols (U+1D400โ€“U+1D7FF): bold, italic, script, fraktur, double-struck, monospace, sans-serif.
  • Enclosed Alphanumerics (U+2460โ€“U+24FF): the โ“‘โ“คโ“‘โ“‘โ“›โ“” circled letters.
  • Halfwidth and Fullwidth Forms (U+FF00โ€“U+FFEF): the ๏ฝ—๏ฝ‰๏ฝ„๏ฝ… vaporwave spacing.
  • Plus scattered small-caps, superscripts, and regional-indicator pairs (flag emoji).

Why it survives a copy-paste into any bio

Because the styling lives in the character, not in CSS, it travels as plain text. A bio field just stores a Unicode string; it has no idea that some of those code points happen to look like a curly H. That "the style rides along with the text" property is exactly why these spread โ€” the output is portable by construction, so it carries into places that never gave you a formatting toolbar.

Generating it is just a lookup table

There's no clever algorithm here. You map each ASCII letter to the same offset inside the target block:

// ASCII Aโ€“Z โ†’ Mathematical Script uppercase, which starts at U+1D49C
const script = (ch) => {
  const i = ch.charCodeAt(0) - 65;            // A = 0
  if (i < 0 || i > 25) return ch;             // leave non-letters alone
  return String.fromCodePoint(0x1D49C + i);   // ๐’œ, โ„ฌ, ๐’ž, โ€ฆ
};
[..."HELLO"].map(script).join("");            // ๐“—๐“”๐“›๐“›๐“ž
Enter fullscreen mode Exit fullscreen mode

โ€ฆthen you keep one table per style. The reason a ready-made fancy text generator can show dozens of styles at once is just dozens of these maps applied in parallel โ€” the same trick powers variants like bubble text.

The three gotchas nobody mentions

The fun stops the moment this text meets a machine instead of a human eyeball:

  1. Accessibility takes a hit. A screen reader doesn't see a stylish H โ€” it sees MATHEMATICAL SCRIPT SMALL H, and will either read that aloud literally or skip the character. A bio written entirely in fancy text can be unreadable to assistive tech. Use it for a flourish, not your whole name.

  2. It's invisible to search and matching. ๐“ณ๐“ธ๐“ฑ๐“ท and john are different byte sequences, so naรฏve search, @-mentions, and username lookups won't connect them. If you store user-supplied text, this will bite you.

  3. Normalization folds it back โ€” and that's the fix. Run the string through Unicode NFKC normalization and most of these styles collapse back to plain ASCII:

"๐“ณ๐“ธ๐“ฑ๐“ท".normalize("NFKC"); // "john"
Enter fullscreen mode Exit fullscreen mode

That one line is how you make fancy text searchable, validate a username, or strip decoration server-side.

So the whole thing is: Unicode has spare alphabets, the styling is baked into the code point rather than the CSS, and NFKC is the undo button. Handy to know whether you're decorating a bio or sanitizing one.

Top comments (0)