@规则:@font-face
@font-face 是 CSS 的 at-规则,用于在网页加载自定义字体。字体来源可以是远程服务器资源,也可以是本地字体文件;摆脱系统安装字体的限制,实现设计稿指定特殊字体效果。
实际业务中不会无节制使用网页自定义字体,主要两大痛点:
- 字体文件体积大:尤其中文字体,字符数量庞大,原始
ttf文件可达数 MB,会拖慢页面加载性能; - 多浏览器格式兼容:不同浏览器对字体文件格式支持不一样,需要提供多种格式做降级。
备注:@font-face 最早出现在 CSS2,CSS2.1 被移除,CSS3 重新纳入标准;IE4 就已经支持该规则,并不是 CSS3 才新增能力。
注意:兼容性差异体现在字体文件格式,而不是 @font-face 规则本身。
安全字体栈
不指定自定义字体,浏览器会使用操作系统内置字体。通常需要配置安全字体栈,当特殊字体加载失败时,降级使用系统可用字体,保证页面文字正常展示。
安全字体栈:
font-family: "Helvetica Neue", Helvetica, Arial, "Microsoft YaHei", "Hiragino Sans GB", "Heiti SC", sans-serif;
现代 Web PC(现代浏览器系统 UI 对齐):
font-family: system-ui, "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
移动端 H5 通用:
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
优先中文渲染:
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", Roboto, "Microsoft YaHei", sans-serif;
小程序(微信小程序、Uni-App):
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", Roboto, sans-serif;
全端通用:
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Helvetica, Arial, sans-serif;
字体释义:
system-ui:CSS 标准关键字,自动读取操作系统原生 UI 界面字体;Windows 获取 Segoe UI,macOS 获取 San Francisco。-apple-system:WebKit 私有关键字,仅在 Apple(iOS、macOS)设备生效,调用苹果系统 San Francisco 字体。BlinkMacSystemFont:旧版 macOS Chrome 浏览器兼容降级,用来兼容不识别-apple-system的老版本 Chrome。"Segoe UI":Windows 系统自带的界面无衬线西文字体,用于 Windows 平台英文渲染。Roboto:Android、鸿蒙系统原生默认字体,负责安卓设备中英文基础渲染。"PingFang SC":苹方简体,iOS、新版 macOS 的简体中文字体,苹果设备中文优先项。"Hiragino Sans GB":冬青黑体简体,老版本 iOS、macOS 的中文字体,做老旧苹果设备兼容降级。"Microsoft YaHei":微软雅黑,Windows 平台简体中文字体,避免 Windows 中文回退到宋体;同时兼容 Windows 内核 WebView。Helvetica:旧版 macOS 的西文字体,苹果老设备英文降级备选。Arial:跨平台通用西文字体,Windows、macOS 均预装,作为英文兜底备选。sans-serif:泛字体族,不可省略;前面所有字体都找不到时,交由浏览器默认无衬线字体兜底。
核心原则:
system-ui:现代全平台生效,自动取用操作系统原生 UI 字体;IE11 不识别,需要后续降级字体。-apple-system:苹果全平台(iOS + macOS WebKit)兼容关键字,不只手机。Roboto:主要适配 Android、ChromeOS 设备;其他系统一般无法命中。PingFang SC(苹方)、Microsoft YaHei(微软雅黑):分别做苹果、Windows 平台中文兜底,非对应系统会自动跳过。- 末尾必须写泛字体族
sans-serif,作为最终保底,不可省略。
基本语法
@font-face 只能写在样式顶层,不能嵌套在 CSS 选择器内部。
@font-face {
font-family: <family-name>;
src: url() format() | local(<本地字体名>);
unicode-range: <unicode-range>;
font-weight: <font-weight>;
font-style: <font-style>;
/* 极少业务场景使用 */
font-variant: <font-variant>;
font-stretch: <font-stretch>;
font-feature-settings: <font-feature-settings>;
}
font-family(必填):自定义字体的名称,后续元素通过
font-family引用该名字。字体名包含空格、特殊符号时,需要用引号包裹;
尽量不和系统已有字体重名,避免覆盖系统字体。
src(必填):指定字体资源,支持
url()和local(),多个资源使用逗号分隔。url():加载远程/本地字体文件;跨域服务器返回字体资源时需要配置 CORS,否则会加载失败。format():格式提示,告诉浏览器字体类型。浏览器不识别会直接跳过,不发起无效请求;省略则浏览器一定会下载文件再判断是否可用。local():优先使用用户设备本地已经安装的字体,无需下载网络资源。
unicode-range(可选,性能优化):声明该字体生效的 Unicode 字符范围。如果页面没有用到该区间内的字符,浏览器不会下载这份字体文件。支持单个字符、字符区间、通配符
?。@font-face { font-family: 'FZQCTJT'; src: url('/assets/other/方正清纯体简体.ttf'); unicode-range: U+9701, U+5149, U+6d6e, U+74e6, U+78a7; }font-style(可选):匹配字体样式。
normal、italic、oblique,用来区分同家族下的普通、斜体字体文件。font-weight(可选):匹配字重。支持关键字
normal(400)、bold(700),也支持 1-1000 的数值。
注意:一份字体文件对应一个字重;不要用同一份普通字体文件,设置 font-weight: bold 模拟粗体,浏览器只是算法加粗,效果很差。
主流字体文件格式
| 格式 | 说明 |
|---|---|
.ttf |
TrueType。Windows、Mac 原生常用矢量字体,可自由缩放;老浏览器兼容,体积偏大 |
.otf |
OpenType。基于 PostScript,在 TrueType 基础上扩展更多排版特性 |
.woff |
Web 专用字体格式,对 ttf、otf 做压缩,附带元数据;网页优先选择 |
.woff2 |
woff 的升级版,压缩率更高,体积更小,现代网页首选格式 |
.eot |
Embedded OpenType。微软专为 IE 开发,仅 IE4-IE11 识别,现代项目可不再提供 |
.svg |
基于 SVG 矢量描述字体;老旧 iOS Safari 使用,现代业务基本废弃 |
@font-face {
font-family: 'CustomFont';
src: url('font.woff2') format('woff2'),
url('font.woff') format('woff'),
url('font.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
浏览器兼容性简表:
| 浏览器 | @font-face | TTF/OTF | WOFF | WOFF2 | EOT | SVG |
|---|---|---|---|---|---|---|
| IE | 4+ | 9+ | 9+ | 不支持 | 4+ | 9+ |
| Edge | 12+ | 12+ | 12+ | 14+ | 不支持 | 12+ |
| Firefox | 3.5+ | 3.5+ | 3.6+ | 39+ | 不支持 | 3+ |
| Chrome | 4+ | 4+ | 5+ | 36+ | 不支持 | 4+ |
| Safari | 3.2+ | 3.1+ | 5+ | 14+ | 不支持 | 3.2+ |
浏览器字体下载策略
仅仅写好 @font-face 不会必然触发下载,各浏览器下载时机存在差异:
- IE8:只要定义
@font-face,立刻下载字体,不管页面有没有使用; - Firefox、IE9+:元素应用该字体即可下载,哪怕元素没有任何文本内容;
- Chrome、Safari:不仅要应用字体,元素必须存在真实文本节点,才发起字体下载。
拓展:FOIT、FOUT 字体闪烁问题。字体加载期间,浏览器会出现文字不可见或显示降级字体;可以通过 CSS font-display 属性控制加载期间行为,在字体加载期间,先用系统降级字体显示,字体下载完成再替换。
@font-face {
font-family: 'CustomFont';
src: url('font.woff2') format('woff2');
font-display: swap;
}
网页字体性能优化方案
中文字体字符成千上万,原始文件体积巨大,必须做优化,常用手段:字体子集化、预加载、unicode-range、合理使用 font-display。
font-spider(字蛛)
分析本地 HTML、CSS,自动提取页面出现的字符,生成多格式压缩字体。
# 全局安装
npm install font-spider -g
# 扫描html,生成子集字体
font-spider index.html
- 源字体自动备份在
.font-spider文件夹; - 限制:不识别 JS 动态插入的文本;otf 需要先转 ttf;仅支持 utf-8 文件。
fontmin
百度开源字体处理库,支持 Node API 和 CLI,手动指定需要保留的字符文本。
const Fontmin = require('fontmin')
const fontmin = new Fontmin()
.src('src-font/*.ttf')
.dest('output-font')
.use(Fontmin.glyph({
text: `一夕轻雷落万丝,霁光浮瓦碧参差。有情芍药含春泪,无力蔷薇卧晓枝。`,
hinting: false
}))
fontmin.run(err => {
if(err) throw err
})
字体预加载 preload
提前加载关键字体,适合首屏标题等必须立刻展示的字体;注意需要加上 crossorigin。
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin />
unicode-range
@font-face 下的 unicode-range,声明该字体生效的 Unicode 字符范围。如果页面没有用到该区间内的字符,浏览器不会下载这份字体文件。
字体资源和工具
- 100font.com:专门收集免费商用字体
- 字客网、字体天下等:区分免费、商用授权。商用项目务必使用免费可商用字体,避免版权纠纷。
- convertio:在线字体格式转换器
- cloudconvert:转换任何文件