哪些字体能在本站真渲染

最后更新 2026-11-02

EN中文
本页目录

在检查器里,有些字体能用真正的字形渲染、能量任意字符,有些只能看一张预先画好的样例图。这不是功能没做完,而是两类字体手里的东西根本不同。

两类来源

来源 手里有什么 能做什么
本机字体(src=device) 你机器上的字体文件,取字节要一次授权 真渲染、量任意字符、看 Unicode 覆盖、看完整度量
字体库(src=library) 指纹、元数据、几张样例图 看名字 / 字重 / 度量 / 覆盖;渲染要看样例图或临时载入

库里的字体为什么没有字节

服务端不存字体文件(见 docs/adr/0001):只存指纹(内容哈希)、从字体里抽出来的元数据、以及分析时生成的样例图 SVG。

这不是偷懒。字体文件动辄几 MB,来源许可各不相同,托管就等于分发——那会把项目变成一个字体 CDN,法律与带宽都不是这个站要承担的东西。

「临时载入」做了什么

在库里点「载入」时:

  1. 从上游(GitHub / Google Fonts 的镜像)fetch 拿到字节;
  2. 用 new FontFace(名字, 字节) 注册到 document.fonts,页面就能用这个字体渲染;
  3. 需要量字符的话,同一份字节再交给解析器建一个测量器(按最近使用保留几个,不无限缓存)。

全过程在浏览器内存里,不经过本站的存储,也不会把文件留在磁盘上。

为什么不直接 FontFace(url)

new FontFace(family, 'url(...)') 也能加载字体,但字节被浏览器攥在内部,脚本取不到——于是没法解析它、没法量任意字符。自己 fetch 一份,同一份字节既能注册又能解析,网络流量不变。

代价是 CJK 字体(10 MB 量级)会在内存里多一份拷贝,解析也在主线程(几百毫秒)。所以测量器是可选的。

只有「本机」这一侧才需要授权

queryLocalFonts() 是 Chromium 系浏览器提供的 API:

  • 列出本机字体(家族、样式、PostScript 名):一次全量扫描;
  • 取某个字体的字节:需要用户手势 + 授权。

授权按来源给,但浏览器可能在新一次页面加载后再次询问——所以我们不会在页面打开时"顺手"扫描,所有取字节都发生在你点的那一下。

Safari 与 Firefox 没有这个 API,所以在这两个浏览器里,「本机字体」那一侧整个不可用(首页与贡献页都会按支持情况换文案)。

所以「看不了」的三种情况

  1. Safari / Firefox:「本机字体」入口直接不可用;
  2. 库里字体还没载入:只能看样例图,排版预览与度量是「载入后才有」;
  3. 本机档案里「只探测、没解析」的条目:能选、能预览,但没有 cmapRanges,Unicode 覆盖页会显示「未分析」。

样例图是什么

样例图是分析字体时用它的真实轮廓预先画好的 SVG(每种语言一张),存在对象存储里。它不是截图,也不依赖访客机器上装了什么——所以任何人都能看。

延伸阅读

  • docs/adr/0001-no-font-bytes-on-server.md
  • MDN:Local Font Access API
  • MDN:FontFace、document.fonts