当前内容所在位置(可进入专栏查看其他译好的章节内容)
- 第四部分 视觉增强技术 ✔️
- 【第 12 章 CSS 排版与间距】 ✔️
- 12.1 间距设置
- 12.1.1 使用 em 还是 px
- 12.1.2 对行高的深入思考
- 12.1.3 行内元素的间距设置
- 12.2 Web 字体
- 12.3 谷歌字体
- 12.4 @font-face 的工作原理 ✔️
- 12.4.1 字体格式与回退处理 ✔️
- 12.4.2 同一字型的多种变体形式 ✔️
- 12.5 性能因素考量
文章目录
- 12.4 @font-face 的工作原理及用法 How @font-face works
- 12.4.1 字体格式与回退处理 Font formats and fallbacks
- 12.4.2 同一字型的多种变体形式 Multiple variants of the same typeface
《CSS in Depth》新版封面
12.4 @font-face 的工作原理及用法 How @font-face works
提供字体服务的网站把添加字体的工作做得如此简单易用,但我们仍然有必要了解一下它们是怎么实现的。先来看看谷歌提供的 CSS 文件。在浏览器中打开 URL https://fonts.googleapis.com/css2?family=Roboto:wght@300&family=Sansita:wght@800&display=swap,就可以看到对应字体的 CSS 样式。我们复制其中的一部分,如代码清单 12.8 所示:
代码清单 12.8 定义谷歌字体的示例样式代码
/* 拉丁字符 */
@font-face { /* 每条 @font-face 规则定义一个字体,可在页面其他 CSS 中使用 */font-family: 'Roboto'; /* 声明该字体的名称 */font-style: normal; /* 定义该 @font-face 规则使用的字体样式 */font-weight: 300; /* 定义该 @font-face 规则使用的字体粗细 */font-display: swap;/* 指明字体文件的具体位置 */src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fBBc4AMP6lQ.woff2) format('woff2');unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; /* 该 @font-face 规则使用的 Unicode 编码范围 */
}/* 拉丁字符 */
@font-face {font-family: 'Sansita';font-style: normal;font-weight: 800;font-display: swap;src: url(https://fonts.gstatic.com/s/sansita/v11/QldLNTRRphEb_-V7JLmXWX5-w4dsz_k.woff2) format('woff2');unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face
规则定义了可在页面 CSS 中使用浏览器字体。这里的第一条规则实际上是说,“如果页面需要渲染 font-family
为 Roboto
的拉丁字符,并且这些字符使用了常规的字体样式(非斜体字)、字体粗细为 300
,那么就使用该字体文件”。同理,第二条规则定义了一个字体粗细为 800
的粗体版 Sansita
字体。
font-family
则定义了引用字体的名称,以便在样式表的其他地方生效。src
属性则提供了让浏览器下载该字体的具体位置。
而设置 unicode-range
属性并非 @font-face
正常工作的必要条件。谷歌将其用于性能优化:将最常用的拉丁字符放在一个较小的字体文件中,而将其他字符的扩展集(extended sets)放在额外的文件中。这样,拉丁字符就可以快速下载,而扩展集仅在页面需要时才被浏览器下载。扩展字符集会在谷歌样式表中各自获取对应的 @font-face
规则,例如西里尔字符(Cyrillic)、希腊字符(Greek)、越语字符(Vietnamese)等等。鉴于其基本原理是共通的,因此为确保简洁,代码清单 12.8 中省略了这部分内容。
这里的关键点在于,如果要使用的是线上暂不提供托管服务的付费版字体,您至少得知道如何定义自己的 @font-face
规则。通常,我会先用谷歌字体检索出自己喜欢的、有免费许可的字体,然后将它们下载下来并自行托管。
12.4.1 字体格式与回退处理 Font formats and fallbacks
谷歌提供的这些字体文件都采用了一种名为 WOFF2
的格式。WOFF 即 Web Open Font Format(Web 开发字体格式)的缩写,是一种专为 Web 使用而设计的字体压缩格式。当前所有的现代浏览器都支持 WOFF2
格式,而更新、更好的字体格式还会定期出现。为了应对这种局面,比较稳健的解决方案应该是同时给 WOFF2
与后续的新字体格式提供 URL。代码清单 12.9 假设了一种预想的 WOFF3
格式,并演示了如何基于浏览器的实际支持情况来同时提供这两种配置方案(为提高代码的可读性,这里采用了简化版的 URL)。
代码清单 12.9 支持回退到另一种格式的 Web 字体声明
@font-face {font-family: "Roboto";font-style: normal;font-weight: 300;src: local("Roboto Light"), local("Roboto-Light"),url(https://example.com/roboto.woff3) format('woff3'), /* 使用列表中支持的首个字体格式 */url(https://example.com/roboto.woff2) format('woff2'); /* 不支持 WOFF3 字体的浏览器将回退至 WOFF2 格式 */
}
以上示例代码还用到了一个特殊的 local()
函数,用于指示浏览器先检查用户操作系统中是否已经安装了给定名称的字体。如果确实安装了,则启用该字体;否则将发起一个网络请求下载对应字体。
Web 字体刚刚兴起的时候,由于各个浏览器支持的字体格式参差不齐,开发者不得不引入四五种不同格式的字体;而现在,WOFF2
格式已经得到了各浏览器厂商的广泛支持,因此除非出现更新的字体格式,通常情况下无需考虑上述写法。
12.4.2 同一字型的多种变体形式 Multiple variants of the same typeface
如果要用到同种字型(typeface)下的多种字体,那么每一种字体都需要定义各自的 @font-face
规则。如果在谷歌字体界面上同时选取了 Roboto
字型的细体版和粗体版,谷歌就会提供一个形如 https://fonts.googleapis.com/css2?family=Roboto:wght@300;700&display=swap
的样式表 URL。在浏览器中打开该 URL 并查看样式代码,这里截取了其中一部分,如代码清单 12.10 所示:
代码清单 12.10 定义同一字型下两种不同粗细的字体
/* 拉丁字符 */
@font-face {font-family: 'Roboto'; /* 细体 Roboto */font-style: normal; /* 细体 Roboto */font-weight: 300; /* 细体 Roboto */font-display: swap;src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fBBc4AMP6lQ.woff2) format('woff2');unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
…
/* 拉丁字符 */
@font-face {font-family: 'Roboto'; /* 粗体 Roboto */font-style: normal; /* 粗体 Roboto */font-weight: 700; /* 粗体 Roboto */font-display: swap;src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfBBc4AMP6lQ.woff2) format('woff2');unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
上述代码片段展示了两种不同 Roboto
字体的定义方法。如果页面需要渲染字体粗细为 300
的 Roboto
字体,则会启用第一种定义;若是需要渲染字体粗细为 700
的 Roboto
字体,则会启用第二种。
但如果页面样式需要用到其他版本的字体(如 font-weight: 500
或者 font-style: italic
),浏览器则会尽可能从已有的两种字体定义做近似选择。也就是说,通常情况下浏览器会选择与所需字体更接近的版本。不过这取决于浏览器,偶尔也可能会把某个已有字体变为斜体或者加粗来趋近预期的效果;例如通过使用几何学方法来实现,产生 “伪加粗”(“faux bold”)或者 “伪斜体字”(“faux italic”)效果。但这样的效果肯定不如原生设计的字体效果好。因此,遇到只能使用 Web 字体中仅限 @font-face
规则声明的字体粗细与样式的情况时,您应当慎之又慎。
在使用谷歌字体或者其他字体服务提供商时,通过界面操作就可以获取到所需的代码。有时可能服务商没有提供您要找的字体,此时就需要自己搭建字体服务,利用 @font-face
规则来定义浏览器需要的字体格式。
关于《CSS in Depth》(中译本书名《深入解析 CSS》)
第 1 版 | 第 2 版 | |
---|---|---|
读者评分 | 原版:4.7(亚马逊);中文版:9.3(豆瓣) | 原版:5.0(亚马逊);中文版:暂无,待出版 |
出版时间 | 原版:2018 年 3 月;中文版:2020 年 4 月 | 原版:2024 年 7 月;中文版:暂无,待出版 |
原价 | 原版:$44.99;中文版:¥139.00 | 原版:$59.99;中文版:暂无,待出版 |
现价 | 原版:$36.49;中文版:¥52.54 起步 | 原版:$52.09;中文版:暂无,待出版 |
原版国内预订 | 起步价 ¥461.00 | 起步价 ¥750.00 |
本专栏为该书第 2 版高分译文专栏,全网首发,精译精校,持续更新,计划今年内完成全书翻译,敬请期待!!!
目前已完结的章节(可进入本专栏查看详情,连载期间完全免费):
- 第一章 层叠、优先级与继承(已完结)
- 1.1 层叠
- 1.2 继承
- 1.3 特殊值
- 1.4 简写属性
- 1.5 CSS 渐进式增强技术
- 1.6 本章小结
- 第二章 相对单位(已完结)
- 2.1 相对单位的威力
- 2.2 em 与 rem
- 2.3 告别像素思维
- 2.4 视口的相对单位
- 2.5 无单位的数值与行高
- 2.6 自定义属性
- 2.7 本章小结
- 第三章 文档流与盒模型(已完结)
- 3.1 常规文档流
- 3.2 盒模型
- 3.3 元素的高度
- 3.4 负的外边距
- 3.5 外边距折叠
- 3.6 容器内的元素间距问题
- 3.7 本章小结
- 第四章 Flexbox 布局(已完结)
- 4.1 Flexbox 布局原理
- 4.2 弹性子元素的大小
- 4.3 弹性布局的方向
- 4.4 对齐、间距等细节处
- 4.5 本章小结
- 第五章 网格布局(已完结)
- 5.1 构建基础网格
- 5.2 网格结构剖析 (上)
- 5.2.1 网格线的编号(下)
- 5.2.2 网格与 Flexbox 配合(下)
- 5.3 两种替代语法
- 5.3.1 命名网格线
- 5.3.2 命名网格区域
- 5.4 显式网格与隐式网格(上)
- 5.4.1 添加变化 (中)
- 5.4.2 让网格元素填满网格轨道(下)
- 5.5 子网格(全新增补内容)
- 5.6 对齐相关的属性
- 5.7 本章小结
- 第六章 定位与堆叠上下文(已完结)
- 6.1 固定定位
- 6.1.1 创建一个固定定位的模态对话框
- 6.1.2 在模态对话框打开时防止屏幕滚动
- 6.1.3 控制定位元素的大小
- 6.2 绝对定位
- 6.2.1 关闭按钮的绝对定位
- 6.2.2 伪元素的定位问题
- 6.3 相对定位
- 6.3.1 创建下拉菜单(上)
- 6.3.2 创建 CSS 三角形(下)
- 6.4 堆叠上下文与 z-index
- 6.4.1 理解渲染过程与堆叠顺序(上)
- 6.4.2 用 z-index 控制堆叠顺序(上)
- 6.4.3 深入理解堆叠上下文(下)
- 6.5 粘性定位
- 6.6 本章小结
- 第七章 响应式设计(已完结)
- 7.1 移动端优先设计原则(上篇)
- 7.1.1 创建移动端菜单(下篇)
- 7.1.2 给视口添加 meta 标签(下篇)
- 7.2 媒体查询(上篇)
- 7.2.1 深入理解媒体查询的类型(上篇)
- 7.2.2 页面断点的添加(中篇)
- 7.2.3 响应式列的添加(下篇)
- 7.3 流式布局
- 7.4 响应式图片
- 7.5 本章小结
- 第八章 层叠图层及其嵌套
- 8.1 用 layer 图层来操控层叠规则(上篇)
- 8.1.1 图层的定义(上篇)
- 8.1.2 图层的顺序与优先级(下篇)
- 8.1.3 revert-layer 关键字(下篇)
- 8.2 层叠图层的推荐组织方案
- 8.3 伪类 :is() 和 :where() 的用法
- 8.4 CSS 嵌套的使用
- 8.4.1 嵌套选择器的使用
- 8.4.2 深入理解嵌套选择器
- 8.4.3 媒体查询及其他 @规则 的嵌套
- 8.5 本章小结
- 第九章 CSS 的模块化与作用域
- 9.1 模块的定义
- 9.1.1 模块和全局样式
- 9.1.2 一个简单的 CSS 模块
- 9.1.3 模块的变体
- 9.1.4 多元素模块
- 9.2 将模块组合为更大的结构
- 9.2.1 模块中多个职责的拆分
- 9.2.2 模块的命名
- 9.3 CSS 的作用域
- 9.3.1 CSS 作用域的就近原则
- 9.3.2 划定作用域的边界
- 9.3.3 CSS 中的隐式作用域
- 9.3.4 关于 CSS 作用域与层叠图层
- 9.4 CSS 模式库
- 9.5 本章小结
- 第十章 CSS 容器查询
- 10.1 容器查询的一个简单示例
- 10.1.1 容器尺寸查询的用法
- 10.2 深入理解容器
- 10.2.1 容器的类型
- 10.2.2 容器的名称
- 10.2.3 容器与模块化 CSS
- 10.3 与容器相关的单位
- 10.4 容器样式查询的用法
- 10.4.1 将模块与所在容器解耦
- 10.4.2 减少重复代码
- 10.5 本章小结
- 第 11 章 颜色与对比
- 11.1 通过对比进行交流
- 11.1.1 模式的建立
- 11.1.2 还原设计稿
- 11.2 颜色的定义
- 11.2.1 色域与色彩空间
- 11.2.2 CSS 颜色表示法(RGB、Hex、HSL、HWB、LAB/OKLAB、LCH/OKLCH)
- 11.3 利用 OKLCH 处理颜色(上篇)
- 11.3.4 从页面其他颜色衍生出新颜色(下篇)
- 11.4 思考字体颜色的对比效果
- 11.5 本章小结
- 附录
- 附录A:CSS 选择器参考
- 附录B:CSS 预处理器简介