R3.13.3icon font fallback设计

图标字体加载失败会留下无意义字符

别名: icon font · PUA · 图标字体 · tofu · ligature icons

概念解释

图标字体把图形编码成字体里的字形,通常放在私用区(PUA)或靠连字把字母序列替换成图标。字体没到、被拦截、子集里没有那一码,浏览器不会留下一块空白图,而会按普通字符回退:方框、tofu、空白、或作者当初当图标用的那个字母。对读屏,那是一个仍在文本流里的字符,会把码位或字母读出来。失败留下的是无意义字符,不是「图标没画出来」。

它处理的是图标字体这条失败形态,不是正文 FOIT/FOUT 的取舍,也不是中文正文要不要分片。

机制

文本布局把每个码位映射到当前字体的一个 glyph。PUA 码位在系统回退链里通常没有对应图形,于是出现 .notdef 方框或空白;若图标其实是 content: "\e001" 这类私用码,失败时屏幕上就是豆腐块。连字派把 content: "home" 或类名对应的字母画成房子图标,字体一失败,「home」或单个字母就以真文字出现在按钮里。无论哪一种,节点仍是文本:复制会得到怪字符,翻译工具会试图翻译它,屏幕阅读器按字符名称朗读,搜索会命中这些字母。

SVG、内联 path、<img> 的失败与此不同。图没加载可以不渲染、走 alt、或留下有尺寸的空位;它不向文本流注入一个码位。图标字体把「图形」寄生在文本管道里,所以文本管道的回退规则原样生效——而这套规则是为「缺字的语言」设计的,不是为「缺的是一张图」设计的。

边界

字体已缓存且从不更新的内部工具,失败率可以很低,但一旦 CDN 被拦、企业网络剥字体、用户开了「不允许远程字体」,字符立刻露出来。把图标字体只用于纯装饰且 aria-hidden 的场景,读屏噪音会小,视觉上的怪字符仍在。emoji 字体和系统符号字体走平台回退,缺的是另一套彩色字形,不是 PUA 豆腐,不要混为一谈。可变字体、子集化针对的是正文缺字和体积,修的不是「图标失败成字符」。CSS content 里的图标字符串在伪元素上,有的读屏会跳过伪元素,有的不会,不能当无障碍方案。

怎么落地

  • 交互图标改用 SVG、内联 path 或带 alt / 可访问名称的 <img>;不要把可操作含义放进图标字体的码位。
  • 若暂时仍用图标字体:每个图标节点提供文本替代(可见文字或 aria-label),并把装饰性码位 aria-hidden="true";为字体失败准备 font-display: optional 仍不够——optional 失败一样留下字符。
  • 禁止用字母连字当图标(失败会露出单词);禁止把 PUA 字符写进可复制、可翻译的正文。
  • 验证:在开发者工具里禁用该字体或阻断其网络请求,看每个图标位置出现的是空白/替代图,还是方框、字母、可读出的码位。用读屏听失败态:不应读出「private use」或「home」这类字。复制按钮,剪贴板里不应出现怪字符。

延伸

  • 同组R3.13.1 不可见文本与换字闪烁是同一取舍的两端 · R3.13.2 伪造字重与斜体会改变文字的可读性
  • 相邻R3.06 字体加载 · R3.07 图片与媒体优化
  • 站内检索icon font · PUA · tofu · icon font fallback

同组卡片

快捷操作

分享

分享当前页面

ios_share

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