R3.13.3icon font fallbackdesign

Failed icon fonts leave meaningless characters

Aliases: icon font · PUA · tofu · ligature icons · .notdef

What it is

An icon font encodes pictures as glyphs, usually in the Private Use Area (PUA) or via ligatures that replace a letter sequence with an icon. If the face never arrives, is blocked, or the subset lacks that codepoint, the browser does not leave a blank image. It falls back as ordinary text: boxes, tofu, gaps, or the letter the author used as the icon. To a screen reader that is still a character in the text stream, spoken as a codepoint or a letter. Failure leaves a meaningless character, not "the icon didn't draw".

This is that failure mode — not the FOIT/FOUT tradeoff for body text, and not whether CJK body faces should be subsetted.

Why it happens

Text layout maps each codepoint to a glyph in the current face. PUA codepoints usually have no picture in the system fallback chain, so .notdef boxes or blanks appear; if the icon is content: "\e001" and the face fails, the screen shows tofu. Ligature-based sets draw content: "home" (or a class's letter) as a house icon; when the face fails, "home" or that letter appears as real text inside the button. Either way the node is still text: copy yields a strange character, translation tools try to translate it, screen readers speak the character name, search hits those letters.

SVG, inline paths, and <img> fail differently. A missing image can omit paint, use alt, or leave a sized hole; it does not inject a codepoint into the text stream. Icon fonts parasitise the text pipeline, so the pipeline's fallback rules apply as designed — and those rules exist for missing language glyphs, not for a missing picture.

Where it stops holding

Internal tools whose icon face is cached and never updated can fail rarely, but a blocked CDN, an enterprise network that strips fonts, or "allow no remote fonts" exposes the characters at once. Using icon fonts only as decoration with aria-hidden reduces screen-reader noise; the visual garbage remains. Emoji fonts and system symbol fonts follow platform fallback into other colour glyphs, not PUA tofu; do not conflate them. Variable fonts and subsetting address body coverage and weight, not "the icon became a character". Icon strings in CSS content sit on pseudo-elements; some screen readers skip those, some do not — that is not an accessibility strategy.

Applying it

  • Ship interactive icons as SVG, inline paths, or <img> with alt / an accessible name. Do not put operable meaning in an icon-font codepoint.
  • If an icon font remains: give every icon a text alternative (visible text or aria-label) and aria-hidden="true" the decorative codepoint. font-display: optional is not enough — optional failure still leaves the character.
  • Do not use letter ligatures as icons (failure reveals the word). Do not put PUA characters in copyable, translatable text.
  • How to check: disable the face in devtools or block its request. Each icon slot should show a blank or a replacement graphic, not a box, a letter, or a speakable codepoint. With a screen reader in the failed state: it must not speak "private use" or "home". Copy the button; the clipboard must not contain a strange character.

Related

  • Same group: R3.13.1 Invisible text and swap-flash are two ends of one tradeoff · R3.13.2 Faux-bold and faux-italic change how text can be read
  • Nearby: R3.06 Font Loading · R3.07 Images and Media
  • Search terms: icon font · PUA · tofu · icon font fallback

Cards in the same group

Quick Actions

Share

Share this page

ios_share

https://hci.top/en/handbook/R3.13.3