每个前端开发者都曾与 @font-face 打过交道,但真正理解这些字体格式之间区别的人却不多。TTF、OTF、WOFF、WOFF2——它们到底是什么?为什么需要这么多种格式?可变字体又解决了什么问题?
这篇文章将从文件格式的内部结构出发,梳理这些格式的演变脉络。
一切始于 sfnt
要理解字体格式,首先要理解一个核心概念——sfnt。这是 Apple 在 1980 年代末为 TrueType 设计的一种容器结构,本质上是一个表集合(table-based)的二进制格式:
sfnt container├── 目录表 (offset table)├── 'cmap' — 字符到字形映射├── 'glyf' — 字形轮廓数据├── 'head' — 字体头部信息├── 'hhea' — 水平排版指标├── 'hmtx' — 水平度量├── 'maxp' — 最大需求├── 'name' — 名称表├── 'os/2' — OS/2 与 Windows 指标└── ...每一个表(table)都由一个四字符标签标识,承担特定的排版功能。这种架构影响深远——后续所有主流字体格式(TTF、OTF、WOFF、WOFF2)都在此基础上构建。
TTF — TrueType
TrueType 由 Apple 于 1991 年发布,随后 Microsoft 获得授权并共同推广。它使用二次贝塞尔曲线来描述字形轮廓。
MIME 类型: font/ttf
优点:
- 兼容性极广,几乎所有操作系统都能原生渲染
- 二次贝塞尔曲线计算简单,渲染性能好
缺点:
- 文件体积较大,未经压缩
- 缺少高级排版特性(如连字、花体替代等)的标准支持
- 不适用于直接网络分发
TrueType 中的字形数据直接存储在 glyf 表中,每个字形由一系列的轮廓(contour)组成。这种设计虽然简单,但也意味着包含大量汉字的字体文件会非常庞大——一个完整的中文字体可能轻松超过 10MB。
TrueType 是 Apple 与 Adobe 的 PostScript Type 1 竞争的产品。Type 1 使用三次贝塞尔曲线,TrueType 选择使用二次贝塞尔曲线以绕过 Adobe 的专利。(MDN: TrueType)
OTF — OpenType
OpenType 是 Microsoft 与 Adobe 于 1996 年联合发布的格式,本质上是 TrueType 的超集。它做了两件关键的事:
- 支持 PostScript 轮廓——可以使用三次贝塞尔曲线(CFF / Type 2 程序)
- 引入排版特性表——
GSUB、GPOS、GDEF等
OpenType font├── sfnt 容器├── TrueType 轮廓 (二次贝塞尔) 或 CFF 轮廓 (三次贝塞尔)├── 'GSUB' — 字形替换 (用于连字、小大写等)├── 'GPOS' — 字形定位 (用于kerning、标记附着等)├── 'GDEF' — 字形定义└── ...MIME 类型: font/otf
关键区别在哪?
一个 OTF 文件可以包含 TrueType 轮廓(这时它本质上和 TTF 几乎一样,只是多了 OpenType 特性表),也可以包含 CFF (PostScript) 轮廓。前者通常以 .otf 为扩展名但内部仍是 TrueType 轮廓——这容易造成混淆。
OpenType 规范由 Microsoft 和 Adobe 共同维护。它的
GSUB/GPOS表机制使得连字、序号、花体替代等高级排版特性成为可能。(Microsoft OpenType Specification)
WOFF — Web Open Font Format
WOFF 诞生于 2009 年,由 Mozilla、Type Supply、LettError 等组织合作开发,专门为解决字体在 Web 上的分发问题而设计。
WOFF 做的事情很简单:将 sfnt 容器中的表数据压缩,并加入元数据(如许可证信息)。
MIME 类型: font/woff
压缩方式:
- 对单个表使用 gzip 压缩(
compress2函数) - 对某些已压缩的表(如
glyf)使用 lz77 编码
这是一个关键设计决策:WOFF 不是对整个文件做整体压缩,而是对每个表单独压缩。这使得浏览器可以按需解压——只解压当前需要的表,而不必解压整个字体文件。
WOFF 规范由 W3C 标准化,核心优势是压缩率和对字体厂商许可条款的支持——许多不愿授权 TTF/OTF 给 Web 使用的厂商,愿意授权 WOFF 格式。(MDN: WOFF)
WOFF2 — 第二代 Web 字体格式
WOFF2 于 2016 年成为 W3C 推荐标准,相比 WOFF 实现了显著更好的压缩率——通常比 WOFF 小 30–50%。
压缩算法:
WOFF2 使用了一个名为 Brotli 的压缩算法(Google 开发,与 WOFF 的 gzip 相比,压缩率大幅提升)。但更重要的是,WOFF2 在压缩策略上做了重大改进:
- 表重组——WOFF2 将 sfnt 表的数据重新排列,使得相似类型的数据聚集在一起,利于压缩
- 公共表分解——多个字体共用的表(如
loca、hmtx)被提取出来,避免重复存储 - 微调指令压缩——字体的微调指令(
fpgm、prep、cvt)使用专用的压缩方法 - 轮廓数据转换——对
glyf/CFF轮廓数据做专门的编码优化
MIME 类型: font/woff2
对比一下压缩效果:
| 格式 | 原始文件 | 压缩后 | 压缩率 |
|---|---|---|---|
| TTF | 100% | — | 0% |
| OTF | 100% | — | 0% |
| WOFF (gzip) | 100% | ~40% | ~60% |
| WOFF2 (Brotli) | 100% | ~25–35% | ~65–75% |
WOFF2 的 Brotli 压缩比 WOFF 的 gzip 提供 30–50% 的额外压缩率,当前所有现代浏览器均支持。(W3C WOFF2 Specification)
/* 推荐的最佳实践:优先使用 WOFF2,回退到 WOFF */@font-face { font-family: "MyFont"; src: url("myfont.woff2") format("woff2"), url("myfont.woff") format("woff"), url("myfont.otf") format("opentype"); font-display: swap;}MDN 官方的建议是:“For web delivery, it’s generally best to serve fonts in WOFF2 format”,并指出 WOFF2 压缩效率更高,在现代浏览器中也得到良好支持,是大多数网站的安全默认选择。(MDN: @font-face)
可变字体 (Variable Fonts)
2016 年,Microsoft、Adobe、Apple、Google 联合发布了 OpenType 1.8 规范,其中引入了可变字体(Variable Fonts)。这可能是字体技术自 TrueType 以来的最大突破。
核心思想: 一个字体文件包含一个或多个**轴(axis)**上的所有变化,而不是为每个字重/字宽/样式准备单独的文件。
静态字体(传统方式): MyFont-Regular.ttf (20KB) MyFont-Bold.ttf (20KB) MyFont-Italic.ttf (22KB) MyFont-BoldItalic.ttf (22KB) Total: ~84KB
可变字体: MyFont-Variable.woff2 (45KB) — 包含所有字重、字宽、斜体注册轴
OpenType 规范定义了 5 个注册轴(registered axes),它们都有对应的 CSS 属性:
| 轴标签 | 名称 | CSS 属性 | 值范围 |
|---|---|---|---|
wght | 字重 (Weight) | font-weight | 1–1000 |
wdth | 字宽 (Width) | font-stretch | 百分比 |
ital | 斜体 (Italic) | font-style | 0 或 1 |
slnt | 倾斜 (Slant) | font-style: oblique | -90–90 度 |
opsz | 光学尺寸 (Optical Size) | font-optical-sizing | 对应字号 |
自定义轴
除了注册轴,字体设计师可以定义任意数量的自定义轴,使用四个大写字母作为标签。例如,GRAD(Grade)轴可以在不改变文本布局的情况下调整字重——这对于动画非常有用,因为不会触发 reflow。
/* 使用标准属性 */h1 { font-weight: 450; font-stretch: 85%; font-optical-sizing: auto;}
/* 使用低阶 API 访问自定义轴 */h2 { font-variation-settings: "wght" 575, "GRAD" 88;}@font-face 的变化
使用可变字体时,@font-face 中需要指定允许的数值范围:
@font-face { font-family: "MyVariableFont"; src: url("my-font.woff2") format("woff2-variations"); font-weight: 300 900; font-stretch: 75% 125%; font-style: normal;}注意:有些浏览器尚未实现
format("woff2-variations")的全部语法。支持可变字体的浏览器在使用woff2而非woff2-variations时也能正常渲染,但建议在可能的情况下使用正确的语法。可以结合@supports特性查询进行降级处理。(MDN: Variable Fonts)
浏览器兼容性检测
h1 { font-family: Fallback-Font, sans-serif;}
@supports (font-variation-settings: "wdth" 115) { h1 { font-family: MyVariableFont, sans-serif; }}格式对比总览
| 属性 | TTF | OTF | WOFF | WOFF2 | 可变字体 |
|---|---|---|---|---|---|
| 发布年份 | 1991 | 1996 | 2009 | 2016 | 2016 |
| 压缩 | 无 | 无 | gzip | Brotli | Brotli (通常) |
| 轮廓 | 二次贝塞尔 | 二次/三次贝塞尔 | 同 OTF/TTF | 同 OTF/TTF | 同 OTF |
| 高级排版特性 | 有限 | 完整 (GSUB/GPOS) | 完整 | 完整 | 完整 + 轴 |
| Web 适用性 | 不推荐 | 不推荐 | 推荐 (回退) | 首选 | 推荐 (现代项目) |
| 桌面适用性 | 是 | 是 | 有限 | 有限 | 是 (系统支持) |
如何选择?
面向 Web 分发
WOFF2 → WOFF → OTF / TTF(首选) (回退) (最后手段)当前 Can I Use 显示 WOFF2 在 Chrome、Firefox、Safari、Edge 中均有超过 96% 的全球覆盖率,足以作为主要格式使用。WOFF 作为旧浏览器(主要是 iOS < 5 和旧版 Android)的回退。
面向桌面应用
OTF 是更好的选择。它兼容所有主流操作系统,包含完整的 OpenType 特性,且无需压缩。
面向现代 Web 项目
可变字体 + WOFF2 容器是最优组合。你可以在保持文件体积可控的同时,获得几乎无限的样式变体。推荐一些高质量的可变字体资源:
- Google Fonts — 多数字体现已提供可变版本
- Axis-Praxis — 可变字体在线试玩
- v-fonts.com — 可变字体目录
总结
字体的格式演变是一场不断追求更小体积与更丰富表达能力之间的博弈:
- TTF 奠定了数字化字体的基础架构(sfnt)
- OTF 带来了高级排版特性的标准化
- WOFF 使字体成为一等公民的 Web 资源
- WOFF2 通过 Brotli 和表重组大幅提升了压缩效率
- 可变字体 用一个文件覆盖整个设计空间
每个格式都有它存在的理由。现在当你写 @font-face 时,你看到的就不仅仅是一个 URL,而是一段跨越 30 多年的技术演进史。