CSS 字体模块第 4 级

W3C 工作草案,

更多关于此文档的详细信息
此版本:
https://www.w3.org/TR/2024/WD-css-fonts-4-20240201/
最新发布版本:
https://www.w3.org/TR/css-fonts-4/
编辑草案:
https://drafts.csswg.org/css-fonts-4/
以前的版本:
历史:
https://www.w3.org/standards/history/css-fonts-4/
反馈:
CSSWG 问题库
规范内联
编辑:
Chris Lilley (W3C)
前编辑:
John Daggett (特邀专家)
(前 Apple Inc.)
建议对此规范进行编辑:
GitHub 编辑器
测试套件:
https://wpt.fyi/results/css/css-fonts/

摘要

本规范定义了对现有的 CSS 字体 3 规范的修改以及附加功能。

CSS 是一种用于描述结构化文档(如 HTML 和 XML)在屏幕、纸张等上渲染的语言。

本文档的状态

本节描述了本文档在发布时的状态。 当前 W3C 出版物列表 及该技术报告的最新修订版本 可在 W3C 技术报告索引中找到。

本文档由CSS 工作组作为工作草案发布,使用推荐轨道。 发布为工作草案并不意味着获得了W3C及其成员的认可。

这是一个草案文档, 可能会随时更新、替换 或由其他文档取代。 除作为正在进行的工作外,引用此文档不合适。

请通过在 GitHub 上提交问题(首选)提供反馈, 在标题中包含规范代码 “css-fonts”,如: “[css-fonts] …评论摘要…”。 所有问题和评论都被存档。 或者,可以将反馈发送至www-style@w3.org的公共邮件列表(存档)。

本文档受2023年11月3日 W3C 过程文档的约束。

本文档由根据W3C 专利政策运作的小组制作。 W3C 维护了与该小组的交付物相关的任何专利披露的公共列表; 该页面还包括披露专利的说明。 如果个人确实知道某项专利,并相信该专利包含必要声明,则必须根据W3C 专利政策第6节披露信息。

以下功能存在风险,可能在 CR 期间被删除:

“风险”是 W3C 过程中的术语,并不一定意味着该功能有被删除或延迟的危险。这意味着工作组认为该功能在及时实现互操作性方面可能存在困难,标记为风险功能允许工作组在过渡到建议推荐阶段时在必要时删除该功能,而无需首先发布不包含该功能的新候选推荐。

1. 简介

本规范包含并扩展了CSS3字体规范中描述的基本字体功能 ([CSS-FONTS-3])。

1.1. 值定义

本规范遵循CSS 属性定义约定,并使用值定义语法,这些定义来自[CSS-VALUES-3]。 本规范未定义的值类型将在CSS值与单位模块中定义 [CSS-VALUES-3]。 与其他CSS模块结合时可能会扩展这些值类型的定义。

除了在其定义中列出的特定于属性的值外, 本规范中定义的所有属性 还接受作为其属性值的CSS范围关键词。 为了可读性,未明确重复列出。

2. 基本字体属性

用于呈现字符的特定字体面由 字体系列和应用于给定元素的其他字体属性决定。 此结构允许独立调整设置。

2.1. 字体系列:font-family 属性

名称: font-family
值: [ <family-name> | <generic-family> ]#
初始值: 取决于用户代理
适用于: 所有元素和文本
是否继承:
百分比: 不适用
计算值: 列表,每个项为字符串和/或<generic-family> 关键词
规范顺序: 按照语法
动画类型: 离散
测试

此属性指定了字体系列名称或通用字体系列名称的优先列表。 一个字体系列定义了一组在粗细、宽度或倾斜度上有所变化的字形。 CSS 使用字体系列名称与其他字体属性的组合来选择单个字形。 使用这种选择机制, 而不是像设计应用程序中常用的通过样式名称选择字形, 允许在回退发生时文本显示具有一定的规则性。

组件值是一个逗号分隔的替代列表。 用户代理会遍历字体系列名称列表, 直到匹配到可用的字体, 其中包含要渲染字符的字形。 (参见 § 5.3 字符簇匹配。) 这允许跨平台的可用字体不同, 以及各个字体支持的字符范围不同。

body {
    font-family: Helvetica, Verdana, sans-serif;
}

如果 Helvetica 可用,则会在渲染时使用。 如果 Helvetica 和 Verdana 都不可用, 那么将使用通用字体系列 sans-serif 字体。

字体系列名称有三种类型,其中两种可用于此属性:

<family-name>
字体系列的名称,例如上例中的 Helvetica 或 Verdana。

这可能是本地安装的字体,也可能是网络字体。

<generic-family>
每个 <generic-family> 关键字表示 一种通用字体选择, 并作为一个或多个本地安装字体的潜在别名, 属于指定的通用字体类别。 <generic-family> 可以作为回退使用, 当作者的更具体字体选择不可用时。

通用字体分为三类:

  1. 适用于所有 Unicode 字符的通用字体, 并且总会匹配到一个本地安装的字体。 例如,monospaced

  2. 适用于所有 Unicode 字符的通用字体, 但在某些系统上可能无法匹配到本地安装的字体。 例如,ui-rounded

  3. 针对特定书写系统的通用字体, 仅适用于 Unicode 字符的子集, 并且在某些系统上可能无法匹配到本地安装的字体。 例如,generic(fangsong)

建议作者将通用字体系列作为最后的选择以提高稳健性, 并且在适用时使用更具体的通用字体系列, 即使单独命名的字体系列不可用,也能优先选择特定样式。

请注意,<generic-family> 关键字不能加引号 (否则会被解释为 <family-name>)。

通用字体关键字的集合定义在 § 2.1.5 通用字体系列

<system-family-name>
本地安装的系统字体,其使用受到某些限制。 特别是,它不能用于 font-family 属性, 但可以与 font 速记属性一起使用。

以下值指的是系统字体:

caption
用于标题控件的字体(例如按钮、下拉菜单等)。
icon
用于标注图标的字体。
menu
用于菜单中的字体(例如下拉菜单和菜单列表)。
message-box
用于对话框中的字体。
small-caption
用于标注小控件的字体。
status-bar
用于窗口状态栏中的字体。
测试

2.1.1. <family-name> 语法

<family-name> = <string> | <custom-ident>+

除了通用字体系列或系统字体系列外,字体系列名称必须用 <string> 引号括起来,或不加引号作为一个或多个 <custom-ident> 序列。

注意: 这意味着未加引号的字体系列名称中的大多数标点字符和开头的数字必须进行转义。

为了说明这一点,以下声明是无效的:
font-family: Red/Black, sans-serif;
font-family: "Lucida" Grande, sans-serif;
font-family: Ahem!, sans-serif;
font-family: test@foo, sans-serif;
font-family: #POUND, sans-serif;
font-family: Hawaii 5-0, sans-serif;

任何可能被误解为字体系列值定义中的预定义关键字或 CSS-wide 关键字 的标识符都不被允许。

注意: 这意味着如果你确实有一个字体,其名称与 <generic-family> 名称之一相同,或系统字体名称,或 CSS-wide 关键字 相同,它必须加引号。

为了说明这一点,以下不寻常的字体系列名称是有效的,因为它们被加引号了:
font-family: "sans-serif", sans-serif;
font-family: "default", sans-serif;
font-family: "initial", sans-serif;
font-family: "inherit", sans-serif;

如果一系列标识符被作为 <family-name> 给出,则计算值为通过用单个空格连接序列中的所有标识符生成的字符串名称。

为了避免转义错误,建议将包含空格、数字或除连字符以外的标点字符的字体系列名称加引号:

为字体系列加引号可以防止转义错误。
body { font-family: "New Century Schoolbook", serif }

<body style="font-family: '21st Century', fantasy">

字体系列名称恰好与font-family 关键字值相同的(例如,CSS-wide 关键字,如 inherit<generic-family> 关键字如 serif),必须加引号以避免与同名的关键字混淆。用户代理不得将这些关键字视为与 <family-name> 类型匹配。

2.1.2. <generic-family> 语法

<generic-family> = generic( <custom-ident>+ ) | <string> | <custom-ident>+
最近定义的通用字体系列是使用函数语法来标识的:
body { font-family: "Adobe Fangsong Std R", generic(fangsong), serif}

此示例中的第一个选择是仿宋风格的特定命名字体。由于字体名称中包含空格字符,因此用引号括起来。 第二个是最近添加的特定脚本的通用字体;它是 unicode 范围特定的,因此在某些系统上可能不会与实际安装的字体匹配; 但如果存在,它将是所请求风格的一个示例。第三个是通用的通用字体,确保在所有系统上都能匹配。

2.1.3. <system-family-name> 语法

<system-family-name> = caption | icon | menu | message-box | small-caption | status-bar

2.1.4. 字体族与字体面之间的关系

字体家族名称仅指定一组字体面的名称;它不指定单个字体面。

例如,给定以下字体的可用性,Futura 会匹配,但 Futura Medium 不会:
family and face names
字体族与个别字体面名称

注意: CSS 对选择时使用的字体属性的定义明确不旨在定义字体分类法。 字体设计师对字体家族的定义通常会扩展到沿着标准轴之外的轴变化的字体面集合,如 粗细 (font-weight), 宽度 (font-width) 和 倾斜度 (font-style)。 一个家族可以沿着该家族独有的轴变化。CSS 字体选择机制仅提供在需要替换时确定“最接近”匹配的方式。

注意: 将一组字体分组到字体家族中的具体方式因平台字体管理 API 而异。 例如,Windows GDI API 只允许将四个字体面分组到一个家族中, 而 DirectWrite API、Core Text API 和其他平台支持带有各种粗细、宽度和倾斜度的字体家族 (有关更多详细信息,请参阅 附录 A: 将平台字体属性映射到 CSS 属性)。

有关字体家族名称如何匹配的信息,请参阅下文中的 § 5.1 本地化名称匹配

2.1.5. 通用字体系列

通用字体家族是一个具有标准名称的字体家族(由 CSS 定义),但它是系统上现有安装字体家族的别名。 然而,单个通用字体系列可能是基于字符的 Unicode 范围、 包含元素的内容语言、 用户偏好、系统设置等因素的不同字体组合面。 不同的通用字体系列可能映射到同一个字体。

Tests

注意: 通用字体家族旨在广泛地在许多平台上实现, 不像通常是平台特定名称的任意<family-name>。 预计它们会在不同平台上映射到不同的字体。如果作者希望文本在许多平台上遵循特定的设计, 并且不在乎这些平台上选择的是哪个具体字体,他们可以指定这些通用字体家族名称。

用户代理应为通用字体系列提供合理的默认选择, 以尽可能表达每个系列的特点, 在基础技术允许的范围内。 鼓励用户代理允许用户为通用字体系列选择替代字体。

衬线体 (serif)
衬线字体表示字形带有收笔线条,扩展或收缩的末端,或者真正的衬线结尾(包括 slab serif 字体)。 衬线字体通常是等比例间距的,粗细变化比无衬线体更大。

注意: serifsans-serif 只适用于少数书写系统。 它们在 CSS 中的使用是历史遗留问题,反映了早期 Web 开发的拉丁语中心性。更好的名称可能是“调节字体”和“单线字体”,但为了兼容性,这些名称无法更改。

CSS 使用“serif”术语来指任何书写系统的字体,其他语言中可能使用不同的术语,例如明朝体(日本)、宋体(中国)、仿宋体(中文)或巴塔体(韩文)。 对于阿拉伯语,纳斯赫风格也可对应 serif

serif 至少应映射到一个匹配的字体样式。

注意: 不保证字体样式的字符覆盖范围。因此,映射到的 serif 字体可能不会用于所有内容。

样例衬线字体
样例衬线字体
无衬线体 (sans-serif)
无衬线字体的字形通常是低对比度的(竖直和水平的笔画厚度接近),笔画末端没有任何装饰性元素。无衬线字体通常是等比例间距的,笔画粗细变化较少。 CSS 使用“sans-serif”术语来指任何书写系统的字体,其他语言中可能使用不同的术语,例如哥特体(日本)、黑体(中国)或Gulim(韩文)。

sans-serif 至少应映射到一个匹配的字体样式。

注意: 不保证字体样式的字符覆盖范围。因此,映射到的 sans-serif 字体可能不会用于所有内容。

样例无衬线字体
样例无衬线字体
手写体 (cursive)
手写体的字形通常使用书法风格,结果看起来更像手写的钢笔或毛笔字而不是印刷字体。CSS 使用“cursive”术语来指任何书写系统的字体,其他名称如 Chancery、Brush、Swing 和 Script 也常见于字体名称中。
样例手写体字体
样例手写体字体
奇幻体 (fantasy)
奇幻字体主要是装饰性或表现性的字体,包含装饰或表现性的字符形式,不包括图像字体。
样例奇幻字体
样例奇幻字体
等宽字体 (monospace)
等宽字体的唯一标准是所有字形的宽度相同。此字体通常用于呈现代码示例。

monospace 至少应映射到一个匹配的字体样式。

注意: 不保证字体样式的字符覆盖范围。因此,映射到的 monospace 字体可能不会用于所有内容。

样例等宽字体
样例等宽字体
system-ui
此通用字体家族允许文本以平台上的默认用户界面字体呈现 (与所有 § 2.1.5 通用字体家族 一样,它可能是复合字体)。 跨平台的 UA 应该在其支持的不同平台上使用不同的字体。 system-ui 的目的是让网页内容与原生操作系统的外观和感觉相融合。
Tests

具体使用的字体将取决于 Unicode 覆盖范围和内容语言等因素。

与其他通用字体家族一样, 替换 system-ui 的特定已安装字体不会影响计算样式。
<div id="system-text" style="font-family: system-ui"></div>
...
window.getComputedStyle(document.getElementById("system-text")).getPropertyValue("font-family");

上面的脚本不应了解 system-ui 如何扩展为包括系统用户界面字体的集合。 该脚本应在每个平台上输出“system-ui”结果。

math
此字体家族用于数学表达式。

这些字体可能包含额外的数据 (例如 OpenType MATH 表) 帮助层次化地排版公式。 它们可能包含 风格和伸展字形变体, 有助于数学公式的排版。

generic(fangsong)
该字体家族用于中文仿宋字体。 仿宋是一种介于宋体和楷体之间的放松样式。 它的特点是横线倾斜,端点装饰较小,笔画宽度变化较少。 仿宋常用于中国政府文件。

注意: generic(fangsong) 可能不会映射到任何本地安装的字体, 但如果存在,则该字体会是仿宋风格。

显示中文仿宋字体样例
generic(kai)
此字体家族用于简体和繁体中文,提供书法风格,通常用于官方文件和教材。 楷体可以与其他字体结合,用于需要与其他内容区分的文本,例如标题、引用、引用和对话。

注意: generic(kai) 可能不会映射到任何本地安装的字体, 但如果存在,则该字体会是楷体风格。

显示中文楷体样例
generic(nastaliq)
该字体家族是书写乌尔都语和克什米尔语的标准方式, 也常用于波斯语和其他语言文本中, 尤其是在诗歌等文学体裁中。 其关键特征包括连接字母的倾斜基线, 以及字母和附加符号的复杂成形和定位。 许多字形和连字也有独特的形状。 对于乌尔都语和克什米尔语,不应回退到纳斯赫(naskh)风格。

注意: generic(nastaliq) 可能不会映射到任何本地安装的字体, 但如果存在,该字体将采用 Nastaliq 风格。

السلام علیکم
使用 Nastaliq 字体(Noto Nastaliq Urdu)显示的乌尔都语文本
السلام علیکم
使用回退 Naskh 字体(Scheherazade New)显示的乌尔都语文本
ui-serif
此字体家族用于系统用户界面的衬线变体。 ui-serif 旨在允许网页内容与原生操作系统的外观和感觉相融合。

注意: ui-serif 在没有相应系统字体的平台上预计不会映射到任何字体。

sample ui-serif font
macOS Catalina 和 iOS 13 上的 ui-serif 字体样例:New York
ui-sans-serif
此字体家族用于系统用户界面的无衬线变体。 ui-sans-serif 旨在允许网页内容与原生操作系统的外观和感觉相融合。

注意: ui-sans-serif 在没有相应系统字体的平台上预计不会映射到任何字体。

sample ui-sans-serif font
macOS Catalina 和 iOS 13 上的 ui-sans-serif 字体样例:San Francisco
ui-monospace
此字体家族用于系统用户界面的等宽字体变体。 ui-monospace 旨在允许网页内容与原生操作系统的外观和感觉相融合。

注意: ui-monospace 在没有相应系统字体的平台上预计不会映射到任何字体。

sample ui-monospace font
macOS Catalina 和 iOS 13 上的 ui-monospace 字体样例:SF Mono
ui-rounded
此字体家族用于系统用户界面的圆角字体变体。 ui-rounded 旨在允许网页内容与原生操作系统的外观和感觉相融合。

注意: ui-rounded 在没有相应系统字体的平台上预计不会映射到任何字体。

sample ui-rounded font
macOS Catalina 和 iOS 13 上的 ui-rounded 字体样例:SF Rounded

2.2. 字体粗细: font-weight 属性

名称: font-weight
值: <font-weight-absolute> | bolder | lighter
初始值: normal
应用于: 所有元素及文本
继承:
百分比: 不适用
计算值: 一个数值,见下文
规范顺序: 按语法
动画类型: 根据计算值类型
测试

font-weight 属性指定字体字形的粗细、黑度或笔画厚度。

该属性接受以下值:

<font-weight-absolute> = [normal | bold | <number [1,1000]>]

值的含义如下:

<number [1,1000]>
每个数值表示的粗细至少与前一个值一样黑。 只有大于或等于1,小于或等于1000的值才有效, 其他所有值都为无效。 数字值通常与下列常用的粗细名称对应。
  • 100 - 极细
  • 200 - 超轻(超细)
  • 300 - 轻
  • 400 - 正常
  • 500 - 中等
  • 600 - 半粗(中粗)
  • 700 - 粗体
  • 800 - 特粗(极粗)
  • 900 - 黑体(厚重)

注意: 字体内部可能有其自定义的粗细名称映射, 但这些映射在 CSS 中被忽略。

normal
400 相同。
bold
700 相同。
bolder
指定比继承值更粗的权重。 参见 § 2.2.1 相对权重
lighter
指定比继承值更轻的权重。 参见 § 2.2.1 相对权重

使用非九步权重标度的字体格式应将其标度映射到 CSS 标度, 使得 400 大致对应于标记为 Regular、Book、Roman 的字重, 而 700 大致对应于标记为 Bold 的字重。 或者,可以从与上述标度大致对应的样式名称推断权重。 该标度是相对的, 因此具有更大权重值的字体不得比其他字体看起来更轻。 如果使用样式名称推断权重, 则应注意处理跨语言地区的样式名称差异。

2.2.1. 相对权重

指定的 bolderlighter 值表示相对于父元素字体粗细的权重。 计算出的粗细值基于继承的 font-weight 值,并使用下表进行计算。

继承的值 (w) bolder lighter
w < 100 400 不变
100 ≤ w < 350 400 100
350 ≤ w < 550 700 100
550 ≤ w < 750 900 400
750 ≤ w < 900 900 700
900 ≤ w 不变 700

注意: 上表相当于在字体家族中选择下一个相对的粗体或细体, 包含普通和粗体的字体,以及极细和极重的字体。 如果需要对某个元素使用更精确的权重值, 作者可以使用数字值来代替相对权重。

2.2.2. 缺失的权重

某些字体家族通常只提供少数几种粗细。 当指定的权重没有对应的字体时,会使用一个相邻权重的字体。 一般来说,粗字体映射到权重大于的字体,细字体映射到权重更轻的字体。 (详见 § 5 字体匹配算法 的准确定义。)

以下示例说明不同权重情况下使用的字体。 灰色表示没有存在所需权重的字体,因此使用了相邻权重的字体。
权重为400、700和900的字体家族的权重映射
权重为400、700和900的字体家族的权重映射
权重为300和600的字体家族的权重映射
权重为300和600的字体家族的权重映射

大多数用户代理将字体建模为具有特定的权重, 通常对应于上述九步标度中的一个数值。 虽然这适用于大多数字体,但有些字体可能是可配置的,支持一定范围的权重。 在这种情况下,用户代理会使用一个与所请求的权重尽可能接近的字体 (参见 § 5 字体匹配算法 了解具体算法)。 特别是,对于支持权重范围的字体, 用户代理应表现得像字体在该范围内的每个权重都有存在一样。 对于使用变体的 TrueType / OpenType 字体, 使用 wght 变体来实现变化的权重。 分数权重是有效的。

尽管排版设计师并不热衷于此, 用户代理经常为缺乏实际粗体的字体家族合成粗体。 在字体匹配的过程中, 这些合成的粗体必须被视为字体家族中的一部分。 作者可以通过使用 font-synthesis 属性显式避免这种行为。

2.3. 字体宽度:font-width 属性

名称: font-width
值: normal | <percentage [0,∞]> | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded
初始值: normal
应用于: 所有元素和文本
继承:
百分比: 未解析
计算值: 百分比,见下文
规范顺序: 按语法
动画类型: 按计算值类型
测试

font-width 属性从字体家族中选择普通、压缩或扩展的字形。 值可以是百分比 或映射到百分比的关键词, 如下表所定义:

绝对关键字值 数值
ultra-condensed 50%
extra-condensed 62.5%
condensed 75%
semi-condensed 87.5%
normal 100%
semi-expanded 112.5%
expanded 125%
extra-expanded 150%
ultra-expanded 200%

<percentage [0,∞]> 值表示字形的宽度比例, 100% 表示“正常”字形宽度 (由字体设计者定义)。 小于 0% 的值是 无效的

当不存在特定宽度的字形时, 小于 100% 的值映射到更窄的字形(如果存在),否则映射到更宽的字形。 相反,值大于或等于 100% 时映射到更宽的字形(如果存在),否则映射到更窄的字形。 某些字体可能支持一定范围的宽度值; 如果字体不支持请求的宽度值, 将使用最接近的支持值,并使用相同的映射规则 (参见 § 5 字体匹配算法 了解具体算法)。 对于支持变体的 TrueType / OpenType 字体, 使用 wdth 变体来实现变化的宽度。

下图显示了九个 font-width 属性设置 对字体家族匹配的影响,字体家族包含各种离散宽度。 灰色表示不存在该宽度的字形,因此替换了不同宽度的字形:
宽度映射:包含压缩、正常和扩展字形的字体家族
宽度映射:包含压缩、正常和扩展字形的字体家族

getComputedStyle() 始终将其值序列化为 <percentage>,无论作者如何指定值, 也无论关键字是否恰好映射到该值。

2.3.1. 字体宽度:font-stretch 旧名称别名

出于历史原因,存在一个 font-stretch 属性, 它是旧名称别名,功能与 font-width 相同。

例如,这里在一级标题中使用了旧的 font-stretch
h1 {font-stretch: condensed; }

这些标题上 font-width 的指定值变为 condensed

例如,这里在一级标题中使用了 font-width
h1 {font-width: condensed; }

这些标题上 font-stretch 的指定值变为 condensed

测试

用户代理不得为缺少相应字形且没有宽度变体轴的字体家族合成压缩或扩展字形。 特别是,用户代理不得对这些字形进行几何拉伸。

2.4. 字体样式:font-style 属性

名称: font-style
值: normal | italic | oblique <angle [-90deg,90deg]>?
初始值: normal
应用于: 所有元素和文本
继承:
百分比: 不适用
计算值: 指定的关键字,加上指定的角度(如果有)
规范顺序: 按语法
动画类型: 按计算值类型;normal 动画时表现为 oblique 0deg
测试

font-style 属性允许选择斜体或倾斜的字形。 斜体通常是手写体风格,而倾斜字形则是常规字体的倾斜版本。

对比灰色的 Palatino "a" 和 Baskerville "N" 的人工倾斜渲染与真实的斜体版本:
人工倾斜与真实斜体的对比
人工倾斜与真实斜体的对比

值的含义如下:

normal
匹配被归类为普通字形的字体, 即既不是斜体也不是倾斜字体的。 这代表“0”的倾斜值。
italic
匹配标记为斜体的字体, 或者在没有斜体时匹配倾斜字体。
oblique <angle [-90deg,90deg]>?
控制匹配倾斜字形。 正角度表示顺时针倾斜; 负角度表示逆时针倾斜。 没有 <angle> 表示 14deg。 (注意字体内部可能提供其自己的“oblique”映射, 但字体内部的映射在 CSS 中被忽略。) 接受分数值和负值; 但小于 -90deg 或大于 90deg 的值是 无效的。 如果不存在倾斜字形, 并且 font-synthesis-style 的值为 auto, 将生成合成的倾斜字形。

字体家族可能不包含任何斜体或倾斜字形, 只包含斜体字形而没有倾斜字形, 只包含倾斜字形而没有斜体字形, 同时包含倾斜字形和斜体字形, 或者包含多个不同角度的倾斜字形等各种组合。 字体匹配算法将选择一个符合请求角度符号的字体, 如果存在多个此类字形,则选择最接近请求角度的字形。 一般来说,对于请求的角度大于或等于 11 度的情况, 倾向于选择更大的角度; 否则,倾向于选择较小的角度。 (参见§ 5 字体匹配算法。) 对于使用变体的 TrueType / OpenType 字体, 使用 slnt 变体实现倾斜值, 使用值为 1 的 ital 变体实现斜体值。

注意: OpenType 的 slnt 轴定义 中正角度表示逆时针倾斜, 方向与 CSS 相反。 在使用变体生成倾斜字形时, CSS 实现会考虑这一点。

正负倾斜角度在垂直书写模式中应向哪个方向倾斜? 如何实现相反维度的倾斜 (垂直书写需要)?

如果没有可用的斜体或倾斜字形, 可以通过对未倾斜的字形进行人工倾斜操作来合成倾斜字形。 这些人工倾斜字形的使用 可以通过font-synthesis 属性禁用。

注意: 虽然可以通过人工倾斜常规字形来模拟倾斜字形, 但这并不等同于真实的倾斜字形, 后者在倾斜时会正确保持光学笔画厚度。 最好使用真正的倾斜字体,而不是依赖合成版本。

为了字体匹配的目的, 用户代理可以将 italic 视为 oblique 的同义词。 对于将这些值视为不同的用户代理, 不得为 italic 执行合成。

注意: 作者还应意识到,对于像西里尔字母这样的文字,斜体形式的形状与常规形式非常不同,合成方法可能不适用。 最好使用真正的斜体字体,而不是依赖合成版本。

注意: 许多书写系统缺乏在常规字形中混合手写体形式的传统。 中文、日文和韩文字体几乎从不包含斜体或倾斜字形。 支持多种书写系统的字体有时会省略某些特定书写系统(例如阿拉伯文), 斜体字形集也不支持这些书写系统的字形。 用户代理在跨字体实现合成时, 应谨慎处理跨字体假设的字符映射, 因为字体家族中的斜体字形可能具有与罗马字形不同的 字符映射

2.5. 字体大小:font-size 属性

名称: font-size
值: <absolute-size> | <relative-size> | <length-percentage [0,∞]> | math
初始值: medium
应用于: 所有元素和文本
继承:
百分比: 参考父元素的字体大小
计算值: 一个绝对长度
规范顺序: 按语法
动画类型: 按计算值类型
测试

该属性表示字体字形的期望高度。 对于可缩放字体,font-size 是应用于字体 EM 单位的缩放因子。 对于不可缩放的字体,font-size 将转换为绝对单位, 并与声明的字体大小进行匹配, 使用相同的绝对坐标空间进行匹配。

注意: 对字形应如何适应其 EM 框没有硬性要求。 即使在相同的font-size 下, 不同的字体在视觉上可能呈现出不同的大小。 此外,字形可能会在其 EM 框之外渲染,甚至在其包含块之外渲染,可能导致墨水溢出

值的含义如下:

<absolute-size>
<absolute-size> 关键字引用了用户代理计算并保持的字体大小表中的一项。 参见§ 2.5.1 绝对大小关键字映射表

可能的值有:

[ xx-small | x-small | small | medium | large | x-large | xx-large | xxx-large ]
<relative-size>
<relative-size> 关键字相对于父元素的计算font-size 进行解释, 并可能参照字体大小表。可能的值为:
[ larger | smaller ]

如果父元素在绝对大小关键字映射表中有关键字字体大小,则 larger 可能会计算子元素的字体大小为表中的下一个条目, 而 smaller 可能会将字体大小计算为表中的上一个条目。 例如,如果父元素的字体大小为 font-size:medium, 指定 larger 的值可能会将子元素的字体大小设置为 font-size:large

用户代理可以使用简单的比例代替上表中的下一个和上一个项, 以相对于父元素增加或减少字体大小。 具体比例未指定, 但应在 1.2 到 1.5 之间。 此比例可能因元素而异。

注意: 视障用户可能会请求用户代理使用比默认更高的比例, 以帮助提高可读性。 此外,当用户代理检测到段落文本或标题文本时,它可能会选择使用不同的比例。

<length-percentage [0,∞]>
长度值指定绝对字体大小 (独立于用户代理的字体表)。 负长度无效。

百分比值相对于父元素的计算font-size 指定绝对字体大小。 负百分比无效。

注意: 使用百分比值或字体相对长度emrem 可实现更强大且可级联的样式表。

math
当确定 font-size 属性的计算值时, 必须应用数学缩放规则
以下样式表演示了指定字体大小的多种方法。
p { font-size: 12pt; }
blockquote { font-size: larger }
em { font-size: 150% }
em { font-size: 1.5em }

注意: 此属性的使用值可能与其计算值不同, 原因是font-size-adjust。 但是,子元素继承计算的font-size值, 不受font-size-adjust影响(否则,font-size-adjust 的效果会累加)。

由于某些字体大小的不可用性,此属性的实际值可能与使用值不同。

可以使用 clamp 函数对字体大小进行限制,以实现响应式排版。
font-size: clamp(10px, ..., 36px); 

2.5.1. 绝对大小关键字映射表

下表为用户代理提供了绝对大小缩放因子及其与 HTML 标题和绝对字体大小的映射指南。 medium 值用作参考的中间值。 用户代理可以为不同的字体或显示设备类型微调这些值。

CSS 绝对大小值 xx-small x-small small medium large x-large xx-large xxx-large
缩放因子 3/5 3/4 8/9 1 6/5 3/2 2/1 3/1
HTML 标题 h6 h5 h4 h3 h2 h1
HTML font 大小 1 2 3 4 5 6 7

注意: 在 CSS1 中,建议的相邻索引之间的缩放因子为 1.5, 但用户体验表明这个缩放因子过大。 在 CSS2 中,建议的计算机屏幕相邻索引之间的缩放因子为 1.2, 但这仍然为小尺寸字体带来了问题。 新的缩放因子在每个索引之间变化,以提供更好的可读性。

为了保持可读性,应用这些指南的 UA 仍然应避免创建每 EM 单位少于 9 个设备像素的字体大小。

2.6. 相对大小:font-size-adjust 属性

名称: font-size-adjust
值: none | <number [0,∞]>
初始值: none
应用于: 所有元素和文本
继承属性:
百分比: 不适用
计算值: 数字或关键字 none
规范顺序: 按语法
动画类型: 按计算值类型
测试

对于任意字体大小,不同字体的文本视觉大小和可读性都会有所不同。 对于如拉丁文或西里尔文这样的双字母文字,其大小写字母之间的相对高度是决定可读性的一个因素。 这通常被称为 外形值,其等于字体的 x 高度除以字体大小。

注意: 对于使用变音符号的文本,过大的 x 高度会减少可读性,因为变音符会变得拥挤。

在字体回退的情况下,回退字体的外形值可能与目标字体家族不同,因此可读性较差。 font-size-adjust 属性是一种在字体回退时保持文本可读性的方法。 它通过调整字体大小,使得 x 高度在使用的字体无论是哪一种的情况下都保持一致。

下面的样式定义了 Verdana 作为期望的字体家族, 如果 Verdana 不可用,将使用 Futura 或 Times。 一个段落还指定了 font-size-adjust。
p { 
  font-family: Verdana, Futura, Times; 
} 
p.adj { 
  font-size-adjust: 0.545; 
} 

<p>Lorem ipsum dolor sit amet, ...</p> 
<p class="adj">Lorem ipsum dolor sit amet, ...</p> 

Verdana 的外形值相对较高,为 0.545,这意味着小写字母相对较高, 因此在小字号下文本仍显得清晰可读。 Times 的外形值较低,为 0.447,因此如果发生字体回退, 除非指定了 font-size-adjust,否则在小字号下文本的可读性会比 Verdana 差。

以下展示了使用这些字体渲染的文本比较,列显示了使用 Verdana、Futura 和 Times 渲染的文本。 每行中使用相同的字体大小,并添加了红线以显示 x 高度的差异。 在上半部分,每行渲染的字体大小相同。 下半部分也是如此,但在下半部分还设置了 font-size-adjust 属性为 0.545, 以便调整实际字体大小,使每行中 Verdana 的 x 高度保持一致。 注意下半部分的小字体如何在每行中保持相对清晰可读。

text with and without 'font-size-adjust'
使用和不使用 font-size-adjust 的文本比较

该属性允许作者为元素指定 外形值, 无论是否替换字体,都能有效保持首选字体的 x 高度。 值有以下含义:

none
不保留字体的 x 高度。
<number [0,∞]>
指定在下面计算中使用的 外形值 来计算调整后的字体大小:
c  =  ( a / a' ) s

其中:

s  =  font-size 值
a  =  外形值,由 'font-size-adjust' 属性指定
a' =  实际字体的 外形值
c  =  使用的调整后的字体大小

负值无效。

该值适用于任何被选中的字体,但通常应基于字体家族列表中的第一个字体的 外形值。 如果指定准确,公式中的 (a/a') 项目对第一个字体的影响实际上为 1,因此不会发生调整。 如果指定不准确,在不支持 font-size-adjust 的旧版用户代理中, 使用字体家族列表中的第一个字体渲染的文本将显示不同。

font-size-adjust 的值会影响 font-size 的使用值,但不会影响计算值。 它会影响基于字体度量的相对单位大小, 如 exch,但不会影响 em 单位的大小。 由于 line-height 的数值是基于 font-size 的计算值, font-size-adjust 不会影响 line-height 的使用值。

注意: 在 CSS 中,作者通常会将 line-height 指定为 font-size 的倍数。 由于 font-size-adjust 属性会影响 font-size 的使用值, 在使用 font-size-adjust 时,作者应该小心设置行高。 如果行高设置得过紧,可能会导致文本行重叠。

作者可以通过比较具有相同内容但 font-size-adjust 属性不同的 span 元素, 来计算某个字体的 外形值。 如果使用相同的字体大小,当 font-size-adjust 的值准确时,span 元素将匹配。

使用带边框的两个 span 元素来确定某个字体的 外形值。 这两个 span 元素的 font-size 相同, 但仅为右边的 span 元素指定了 font-size-adjust 属性。 从 0.5 的值开始,可以调整外形值, 直到两个字母周围的边框对齐。

p { 
  font-family: Futura; 
  font-size: 500px; 
} 

span { 
  border: solid 1px red; 
} 

.adjust { 
  font-size-adjust: 0.5; 
} 

<p><span>b</span><span class="adjust">b</span></p> 
Futura with an aspect value of 0.5
Futura 的外形值为 0.5

右边的框稍大于左边的框,因此该字体的 外形值小于 0.5。 调整值直到两个框对齐。

2.7. 简写字体属性: font 属性

名称: font
值: [ [ <'font-style'> || <font-variant-css2> || <'font-weight'> || <font-width-css3> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] | <system-family-name>
初始值: 参见各个属性
适用于: 所有元素和文本
是否继承:
百分比: 参见各个属性
计算值: 参见各个属性
规范顺序: 根据语法
动画类型: 参见各个属性
测试

该属性的语法基于传统的排版速记符号,用于设置与字体相关的多个属性。出于历史和向后兼容的原因,它几乎是一个速记属性。

font 属性是一个速记属性,用于同时设置 font-stylefont-variantfont-weightfont-widthfont-sizeline-heightfont-family

font-variant 属性的值也可以包含在内,但仅限于 CSS 2.1 中支持的值;CSS 字体级别 3 或 4 中新增的 font-variant 值不能在 font 速记中使用:

<font-variant-css2>= [normal | small-caps]

font-width 属性的值也可以包含在内,但仅限于 CSS 字体级别 3 中支持的值,规范中新增的 font-width 值不能在 font 速记中使用:

<font-width-css3>= [normal | ultra-condensed | extra-condensed | condensed |
  semi-condensed | semi-expanded | expanded | extra-expanded |
  ultra-expanded]

因此,我们有以下字体相关属性及其与 font 属性的交互分类:

显式设置

这些属性可以使用 font 属性进行设置:

隐式重置

这些属性不能设置,但会被重置为它们的初始值:

独立级联

这些属性不会被 font 属性设置或重置:

font 属性的所有子属性 在 显式设置隐式重置 组中首先会被重置为它们的初始值。

然后,显式设置 组中的那些显式给定值的属性 在 font 简写中会被设置为这些值。 有关允许和初始值的定义,请参见各个长格式属性定义。

p { font: 12pt/14pt sans-serif }
p { font: 80% sans-serif }
p { font: x-large/110% "new century schoolbook", serif }
p { font: bold italic large Palatino, serif }
p { font: normal small-caps 120%/120% fantasy }
p { font: condensed oblique 12pt "Helvetica Neue", serif; }
p { font: condensed oblique 25deg 753 12pt "Helvetica Neue", serif; }

在第二条规则中,字体大小的百分比值 ("80%") 指的是父元素的计算 font-size。 在第三条规则中,行高百分比 ("110%") 指的是该元素本身的字体大小。

前三条规则没有显式指定 font-variantfont-weight, 因此这些属性会接收其初始值 (normal)。 请注意,字体名称 "new century schoolbook" 包含空格,因此用引号括起来。 第四条规则将 font-weight 设置为 bold, 将 font-style 设置为 italic, 并且隐式将 font-variant 设置为 normal

第五条规则设置了 font-variant (small-caps), font-size(父元素字体大小的120%), line-height(字体大小的120%), 以及 font-family (fantasy)。 因此,关键字 normal 应用于剩余的两个属性:font-stylefont-weight

第六条规则设置了 font-stylefont-widthfont-size, 以及 font-family,其他字体属性被设置为其初始值。

第七条规则将 font-style 设置为 oblique 25deg, 将 font-weight 设置为 753, 并将 font-width 设置为 condensed。 请注意,这条规则中的 25deg 必须紧跟在 "oblique" 关键字之后。

由于 font-width 属性在 CSS 2.1 中未定义, 在 font-width 值出现在 font 规则中时, 作者应包含一个与旧版用户代理兼容的额外版本:

p {
  font: 80% sans-serif;   /* 适用于旧版用户代理 */
  font: condensed 80% sans-serif;
}

系统字体只能整体设置; 也就是说,字体系列、大小、粗细、样式等都必须同时设置。 如果需要,之后可以单独修改这些值。 如果在某个平台上没有符合指定特征的字体, 用户代理应当智能地替换(例如,可以使用较小版本的 caption 字体 来代替 small-caption 字体), 或者使用用户代理的默认字体。 对于常规字体, 如果系统字体的某些单独属性不属于操作系统的可用用户偏好设置, 那些属性应当被设置为其初始值。

这就是为什么这个属性是“几乎”一个简写属性的原因: 系统字体只能通过这个属性来指定, 而不能通过 font-family 自身来指定, 因此 font 允许作者做得比其子属性的总和更多。 然而,像 font-weight 这样的单独属性 仍然会从系统字体中获取值,并可以独立地变化。

请注意,上述系统字体使用的关键字 只有在初始位置时才被视为关键字, 在其他位置相同的字符串会被视为字体系列名称的一部分:

font: menu;        /* 使用系统菜单的字体设置 */
font: large menu;  /* 使用字体系列名称为“menu”的字体 */
button { font: 300 italic 1.3em/1.7em "FB Armada", sans-serif }
button p { font: menu }
button p em { font-weight: bolder } 

如果某系统下用于下拉菜单的字体是例如 9 点的 Charcoal,字体粗细为 600, 那么作为 BUTTON 的后代的 P 元素将显示如下规则:

button p { font: 600 9pt Charcoal }

由于 font 简写属性会将未明确赋值的任何属性重置为初始值, 这与以下声明效果相同:

button p {
  font-style: normal;
  font-variant: normal;
  font-weight: 600;
  font-size: 9pt;
  line-height: normal;
  font-family: Charcoal
}

2.8. 控制合成字体

合成字体是一种回退策略,当字体系列缺少合适的字形时,用以提供接近请求字体的替代方案。

例如,用户代理可能:

合成是一种回退策略,因为最终效果,虽然比没有任何字体要好,但并没有达到为此目的设计的字体的质量。

可变字体,设计者提供了一个或多个变化轴,它们算作字体合成,并且它们的使用不受font-synthesis属性的影响。

2.8.1. 控制合成粗体:font-synthesis-weight属性

名称: font-synthesis-weight
值: auto | none
初始值: auto
适用于: 所有元素和文本
是否继承:
百分比: N/A
计算值: 指定的关键字
规范顺序: 按语法
动画类型: 离散
媒体: 视觉
测试

该属性控制是否允许用户代理合成粗体字形,当字体系列缺少粗体字形时。

auto
允许合成粗体字形
none
不允许合成粗体字形

2.8.2. 控制合成倾斜:font-synthesis-style属性

名称: font-synthesis-style
值: auto | none
初始值: auto
适用于: 所有元素和文本
是否继承:
百分比: N/A
计算值: 指定的关键字
规范顺序: 按语法
动画类型: 离散
媒体: 视觉
测试

该属性控制是否允许用户代理合成倾斜字体字形,当字体系列缺少倾斜字形时。

auto
允许合成倾斜字形
none
不允许合成倾斜字形

在垂直文本中,对于正倾斜角度,字形会被扭曲,使得上边缘向右侧移动,而下边缘向左侧移动。对于负倾斜角度,字形会被扭曲,使得上边缘向左侧移动,而下边缘向右侧移动。扭曲是围绕字形的中心进行的。

垂直文本中的合成倾斜
垂直文本中的合成倾斜,正倾斜角度

2.8.3. 控制合成小型大写字母:font-synthesis-small-caps属性

名称: font-synthesis-small-caps
值: auto | none
初始值: auto
适用于: 所有元素和文本
是否继承:
百分比: N/A
计算值: 指定的关键字
规范顺序: 按语法
动画类型: 离散
测试

该属性控制是否允许用户代理合成小型大写字体字形,当字体系列缺少小型大写字形时。

auto
允许合成小型大写字形
none
不允许合成小型大写字形

2.8.4. 控制合成上标和下标:font-synthesis-position属性

名称: font-synthesis-position
值: auto | none
初始值: auto
适用于: 所有元素和文本
是否继承:
百分比: N/A
计算值: 指定的关键字
规范顺序: 按语法
动画类型: 离散
测试

该属性控制是否要求用户代理为font-variant-position合成上标和下标字形,当字体缺少这些字形时。

auto
要求合成上标和下标字形
none
不允许合成上标和下标字形

2.8.5. 控制合成字体:font-synthesis 简写属性

名称: font-synthesis
值: none | [ weight || style || small-caps || position]
初始值: weight style small-caps position
适用于: 所有元素和文本
是否继承:
百分比: N/A
计算值: 指定的关键字
规范顺序: 按语法
动画类型: 离散
测试

该属性是font-synthesis-weightfont-synthesis-stylefont-synthesis-small-capsfont-synthesis-position属性的简写。其值映射如下:

font-synthesisfont-synthesis-weightfont-synthesis-stylefont-synthesis-small-capsfont-synthesis-position
none none none none none
weight auto none none none
style none auto none none
small-caps none none auto none
position none none none auto
weight style auto auto none none
weight small-caps auto none auto none
weight position auto none none auto
style small-caps none auto auto none
style position none auto none auto
small-caps position none none auto auto
weight style small-caps auto auto auto none
weight style position auto auto none auto
weight small-caps position auto none auto auto
style small-caps position none auto auto auto
weight style small-caps position auto auto auto auto
以下样式规则禁用了阿拉伯语的合成倾斜字体:
*:lang(ar) { font-synthesis: none; }

3. 字体渲染控制

3.1. 字体渲染控制介绍

使用 @font-face 下载 Web 字体时,用户代理需要知道在字体加载过程中该如何处理。 大多数浏览器采用了一定的超时机制:

浏览器 超时 回退 替换
Chrome 35+ 3 秒
Opera 3 秒
Firefox 3 秒
Internet Explorer 0 秒
Safari 3 秒

尽管这些默认行为在某种程度上是合理的,但在不同浏览器之间不一致。 更糟的是,没有一种方法能够覆盖现代用户体验和性能敏感的应用程序所需的所有用例。

Font Loading API [CSS-FONT-LOADING-3] 允许开发者覆盖上述行为, 但这需要编写脚本,且需要大量的工作,并最终无法覆盖 所有 合理的情况。 此外,开发者需要将加载脚本内联到页面中或加载外部库,这会引入额外的网络延迟,进而延迟文本渲染。

注重设计/性能的 Web 开发者通常非常清楚特定 Web 字体对用户体验的重要性。 本规范为开发者提供了控制字体超时和渲染行为的能力。 具体来说,它允许开发者:

3.2. 字体显示时间线

当用户代理首次尝试在页面上使用下载的字体时,启动该字体的字体下载计时器。 该计时器经历三个与字体相关的时间段——阻止期交换期失败期——这决定了使用该字体的任何元素的渲染行为:

要为某个元素使用回退字体进行渲染, 用户代理必须找到该元素的font-family列表中已加载的第一个字体,并使用该字体渲染文本。 执行此操作时不得触发任何回退字体的加载。

要为某个元素使用不可见的回退字体进行渲染, 按照“使用回退字体进行渲染”的方式找到一个字体。 创建一个匿名字体,其指标与选定字体相同,但所有字形均为“不可见”(不包含“墨水”),并使用该字体渲染文本。 执行此操作时不得触发任何回退字体的加载。

fallbackoptional 可能会导致同一字体家族中的某些字体被使用,而其他字体被要求回退,从而呈现出“赎金信”效果。 或许应要求同一字体家族的所有字体具有相同的行为(全部替换或全部回退)? 另见 @font-feature-values,用于基于字体家族控制行为。

4. 字体资源

4.1. @font-face 规则

@font-face 规则允许链接到需要时自动获取和激活的字体。 这使作者可以选择与页面设计目标更匹配的字体,而不是限制在给定平台上可用的一组字体中。 一组字体描述符定义了字体资源的位置,可以是本地的或外部的,并且定义了单个字体的样式特征。 可以使用多个 @font-face 规则来构建具有各种字形的字体家族。 使用 CSS 字体匹配规则,用户代理可以有选择地仅下载需要用于特定文本的字形。

其语法为:

@font-face {
  <declaration-list>
} 
测试

@font-face 规则接受此规范中定义的描述符。

每个 @font-face 规则为每个字体描述符指定一个值,隐式或显式。 在规则中未给出显式值的描述符将采用此规范中列出的初始值。 这些描述符仅适用于定义它们的 @font-face 规则上下文内,不适用于文档语言元素。 没有哪个元素适用这些描述符的概念,也没有值是否由子元素继承的概念。 当给定描述符在某个 @font-face 规则中多次出现时,只有最后一个描述符声明会被使用,之前的所有声明都会被忽略。

使用一个名为 Gentium 的可下载字体:
@font-face { 
font-family: Gentium; 
src: url(http://example.com/fonts/Gentium.woff); 
}

p { font-family: Gentium, serif; } 

用户代理将下载 Gentium 并在渲染段落元素时使用它。如果由于某种原因字体站点不可用,将使用默认的 serif 字体。

一组 @font-face 规则定义了一组字体,可以在包含这些规则的文档中使用。 当进行字体匹配时,使用这些规则定义的字体优先于系统上的其他可用字体。

下载的字体仅对引用它们的文档可用。激活这些字体的过程不应使它们对其他应用程序或未直接链接到相同字体的文档可用。 用户代理实现者可能认为在没有其他可用字体的情况下使用下载的字体来渲染其他文档中的字符是方便的,作为“已安装字体回退”程序的一部分。 然而,这会导致安全泄露,因为一个页面的内容可能会影响其他页面,攻击者可能会利用此作为攻击途径。 这些限制不影响缓存行为,字体的缓存方式与其他网络资源相同。

此 at 规则遵循 CSS 的前向兼容解析规则。 像声明块中的属性一样,用户代理不支持的描述符声明必须被忽略。@font-face 规则需要字体系列和 src 描述符; 如果缺少其中任何一个,@font-face 规则在执行字体匹配算法时不应被考虑。

在用户代理资源有限或实现了禁用可下载字体资源的能力的情况下,@font-face 规则应被简单忽略; 各个描述符的行为应如本规范所定义,不应被更改。

4.2. 字体家族:font-family 描述符

名称: font-family
适用于: @font-face
值: <family-name>
初始值: N/A

此描述符定义了将用于所有 CSS 字体家族名称匹配的字体家族名称。 它会覆盖基础字体数据中包含的字体家族名称。 如果字体家族名称与给定用户环境中可用的字体家族相同, 它会有效地隐藏基础字体,从而影响使用该样式表的文档。 这使网页作者可以自由选择字体家族名称,而无需担心与给定用户环境中存在的字体家族名称冲突。 同样,平台替代给定字体家族名称的情况不应被使用。

4.3. 字体引用:src 描述符

名称: src
适用于: @font-face
值: <font-src-list>
初始值: N/A

此描述符指定包含字体数据的资源。 它的值是以逗号分隔的优先列表,可以是外部引用或本地安装的字体字形名称。 当需要字体时,用户代理会迭代列出的引用集,使用它能够成功解析并激活的第一个引用。 解析此描述符比解析其他描述符更复杂;请参阅 § 4.3.1 解析 src 描述符 以获取解析规则。 激活字体涉及下载文件或从磁盘读取它,解析它,可能还有额外的用户代理依赖步骤。 包含无效数据的字体或未找到的本地字体字形会被忽略,用户代理会加载列表中的下一个字体。

4.3.1. 解析 src 描述符

要解析 <font-src-list> 产生式,请 解析列表中的 <font-src>

<font-src> = <url> [ format(<font-format>)]? [ tech( <font-tech>#)]? | local(<family-name>)
<font-format>= [<string> | collection | embedded-opentype | opentype
 | svg | truetype | woff | woff2 ]
<font-tech>= [<font-features-tech> | <color-font-tech>
 | variations | palettes | 
   incremental-patch | incremental-range | incremental-auto ]
<font-features-tech>= [features-opentype | features-aat | features-graphite]
<color-font-tech>= [color-COLRv0 | color-COLRv1 | color-SVG | color-sbix | color-CBDT ]
测试

尽管建议使用关键字来标识字体格式,但出于向后兼容性的考虑,以下字符串也被接受,并且其效果与使用等效的现代语法相同。

字符串形式 等效语法
format("woff2") format(woff2)
format("woff") format(woff)
format("truetype") format(truetype)
format("opentype") format(opentype)
format("collection") format(collection)
format("woff2-variations") format(woff2) tech(variations)
format("woff-variations") format(woff) tech(variations)
format("truetype-variations") format(truetype) tech(variations)
format("opentype-variations") format(opentype) tech(variations)
测试

注意: CSS 工作组不打算在未来扩展此列表。

如果某个组件值被正确解析并且是 UA 支持的 字体格式字体技术,请将其添加到支持的来源列表中。如果解析组件值时出现解析错误或其格式或技术不被支持,请不要将其添加到支持的来源列表中。

如果在此过程中没有受支持的条目,则 src 描述符的值为解析错误。

这些解析规则允许字体的优雅回退,适用于不支持特定字体技术或字体格式的用户代理。

例如,当不支持增量传输时,提供 woff2 压缩版本的字体以获得最佳性能。 然后,使用 range-request 方法 增量传输时,提供未压缩的 OpenType 字体,以便客户端可以执行字节范围请求。
@font-face { 
font-family: "MyIncrementallyLoadedWebFont"; 
src: url("FallbackURLForBrowsersWhichDontSupportIncrementalLoading.woff2") format("woff2"); 
src: url("MyIncrementallyLoadedWebFont.otf") format(opentype) tech(incremental-range); 
} 

4.3.2. 加载 src 描述符中的单个项目

与 CSS 中的其他 URL 一样,该 URL 可以是相对路径,此时它将相对于包含 @font-face 规则的样式表的位置进行解析。对于 SVG 字体,该 URL 指向包含 SVG 字体定义的文档中的某个元素。如果省略元素引用,则默认引用第一个定义的字体。同样,能够包含多个字体的字体容器格式必须为给定的 @font-face 规则加载且仅加载一个字体。使用片段标识符来指示加载哪个字体;这些片段使用 [RFC8081] 中定义的字体的 PostScript 名称。

测试

符合规范的用户代理在片段标识符未知或不受支持的情况下,必须跳过下载字体资源。例如,不支持 OpenType 集合的旧版用户代理将跳过列表中的下一个 URL。

src: url(fonts/simple.woff);       /* 相对于样式表位置加载 simple.woff */
src: url(/fonts/simple.woff);      /* 从绝对路径加载 simple.woff */
src: url(fonts/coll.otc#foo);      /* 从集合 coll.otc 加载字体 foo */
src: url(fonts/coll.woff2#foo);    /* 从 woff2 集合 coll.woff2 加载字体 foo */
src: url(fonts.svg#simple);        /* 加载 ID 为 'simple' 的 SVG 字体 */

4.3.3. 选择 src 中的项目

外部引用由 URL 组成,后跟一个可选的提示,用于描述该 URL 引用的字体资源的格式。如果格式提示表明字体格式不受支持或未知,或用户代理不支持任何字体技术,则符合规范的用户代理必须跳过下载该字体资源。如果没有提供格式提示,用户代理应下载字体资源。

例如,以下示例展示了如何在可能的情况下加载 WOFF 2 字体,否则加载 WOFF 1,若都不支持则使用 OpenType 字体:
@font-face {
font-family: bodytext;
src: url(ideal-sans-serif.woff2) format("woff2"),
    url(ideal-sans-serif.woff) format("woff"),
  url(basic-sans-serif.ttf) format("opentype");
}
在此示例中,如果不支持 woff2,将跳过不受支持的虚构 "zebra" 格式,下载 opentype 字体:
src: url(ideal.woff2) format("woff2"),url(unsupported.zeb) format("zebra"),
url(basic.ttf) format("opentype");
此示例展示了如何加载集合中的单个实例,或者如果不支持集合,则下载单个字体:
@font-face {
  font-family: 源ノ角ゴシック Code JP;
  src: url(SourceHanCodeJP.otc#Regular) format("collection"),  
    url(SourceHanCodeJP-Regular.ttf) format("opentype");  
}
4.3.3.1. 本地字体回退

当作者希望优先使用本地可用的字体并在字体不可用时下载它时,可以使用 local()。传递给 local() 的本地安装的 <family-name> 参数是一个特定于格式的字符串,用于唯一标识更大字体系列中的单个字体。该名称可以选择用引号括起来。如果不带引号,则遵循 未引号字体家族名称处理规则;换句话说,该名称必须是由空格分隔的标识符序列,这些标识符通过单个空格连接起来形成字符串;因此,CSS 宽泛关键字(如 inherit)和 <generic-family> 关键字(如 serif)不允许出现在 local() 中。

/* Gentium 的常规字体 */
@font-face {
font-family: MyGentium;
src: local(Gentium),    /* 优先使用本地可用的 Gentium */  
  url(Gentium.woff);  /* 否则,下载字体 */  
}  
例如,下面这种使用 local() 的方式是错误的:
@font-face { 
  font-family: foo; 
  src: local(inherit);  
}  

对于 OpenType 和 TrueType 字体,该字符串仅用于匹配本地可用字体的名称表中的 Postscript 名称或完整字体名称。使用哪种类型的名称取决于平台和字体,因此作者应包括这两种名称,以确保在不同平台上正确匹配。对于给定字体名称的替换必须禁止使用。

/* Gentium 的粗体字 */  
@font-face {  
font-family: MyGentium;  
src: local(Gentium Bold),    /* 完整字体名称 */  
  local(Gentium-Bold),    /* Postscript 名称 */  
  url(GentiumBold.woff);  /* 否则,下载字体 */  
font-weight: bold;  
}

@font-face 规则指定单个字体的特性相同,与 local() 一起使用的唯一名称指定的是单个字体,而不是整个字体家族。根据 OpenType 字体数据定义,Postscript 名称位于字体的 名称表中,名称记录的 nameID = 6(请参见 [OPENTYPE] 了解更多详细信息)。Postscript 名称是 OSX 上所有字体常用的键,并且在 Windows 上 Postscript CFF 字体使用。完整字体名称(nameID = 4)用于 Windows 上具有 TrueType 字形的字体。

对于具有多种本地化完整字体名称的 OpenType 字体,必须使用美式英语版本(Windows 的语言 ID 为 0x409,Macintosh 的语言 ID 为 0),或在没有美式英语完整字体名称时使用第一个本地化版本(OpenType 规范建议所有字体至少包含美式英语名称)。同时匹配其他完整字体名称的用户代理(例如,在系统语言设置为荷兰语时匹配荷兰语名称)将被视为不合规。

注意:这样做并不是为了偏向英语,而是为了避免不同字体版本和操作系统本地化之间的匹配不一致,因为字体样式名称(例如“Bold”)通常会被翻译成多种语言,而可用的本地化版本在不同平台和字体版本之间差异很大。

将字体系列名称(nameID = 1)与样式名称(nameID = 2)拼接匹配的用户代理将被视为不合规。

注意:这也允许引用属于无法通过其他方式引用的大型字体家族的面。

使用本地字体或引用另一个文档中的 SVG 字体:
@font-face { 
font-family: Headline; 
src: local(Futura-Medium), 
  url(images/fonts.svg#MyGeometricModern) format("svg"); 
} 

为不同平台上的本地日文字体创建别名:

@font-face { 
font-family: jpgothic; 
src: local(HiraKakuPro-W3), local(Meiryo), local(IPAPGothic); 
} 

引用在大型家族中无法匹配的字体面:

@font-face { 
font-family: Hoefler Text Ornaments; 
/* 与 Hoefler Text Regular 拥有相同的字体属性 */ 
src: local(HoeflerText-Ornaments); 
} 

由于本地化的全名无法匹配,以下头部样式规则的文档始终会使用默认的衬线字体进行渲染,无论系统语言参数是否设置为芬兰语:

@font-face { 
font-family: SectionHeader; 
src: local("Arial Lihavoitu");  /* 芬兰语 Arial Bold 全名,应失败 */ 
font-weight: bold; 
}

h2 { font-family: SectionHeader, serif; } 

符合规范的用户代理将永远不会加载示例中的字体 'gentium.eot',因为它包含在 src 描述符的第一个定义中,该定义在同一个 @font-face 规则中的第二个定义中被覆盖:

@font-face { 
font-family: MainText; 
src: url(gentium.eot);                     /* 供较旧的用户代理使用 */
src: local("Gentium"), url(gentium.woff);  /* 覆盖 src 定义 */ 
} 

4.4. 字体属性描述符:font-stylefont-weight,和 font-width 描述符

名称: font-style
适用于: @font-face
值: auto | normal | italic | oblique [<angle [-90deg,90deg]>{1,2} ]?
初始值: auto
名称: font-weight
适用于: @font-face
值: auto | <font-weight-absolute>{1,2}
初始值: auto
名称: font-width
适用于: @font-face
值: auto | <'font-width'>{1,2}
初始值: auto
测试

这些描述符定义了字体面的特征,并用于将样式匹配到特定的字体面。在通过多个 @font-face 规则定义的字体家族中,用户代理可以下载家族中的所有字体面,或者使用这些描述符选择性地下载与文档中实际使用的样式匹配的字体面。这些描述符的值与相应字体属性的值含义相同,但不允许使用相对关键字,如 bolderlighter。如果省略了这些描述符,则假定使用初始值。如果指定的值超出了与同名属性相同的可接受值范围,则将该描述符视为解析错误。

在这三个描述符中,接受范围来代替单个值。当指定单个值时,它的含义与具有相同起点和终点的范围相同。用户代理必须交换起点和终点的计算值,以禁止递减范围。两个端点都包括在内。这些范围在下面的字体匹配算法中使用。

测试

这些三个描述符的 auto 值具有以下效果:

这些字体面样式属性的值用于替代基础字体数据所暗示的样式。这使得作者可以灵活地组合字体面,即使在原始字体数据的排列方式不同的情况下。实现合成加粗和倾斜的用户代理必须只在字体描述符暗示需要时才应用合成样式,而不是基于字体数据暗示的样式。然而,应用于 '@font-face' 定义的字体的变化值将同时被这些描述符中指定的值以及字体文件本身支持的值所限制。

本节中定义的字体描述符用于从由 @font-face 规则定义的字体集中选择字体。

考虑包含一个常规字体面的家族:

@font-face { 
  font-family: BaskervilleSimple; 
  src: url(baskerville-regular.woff2); 
} 

未设置样式的文本将使用在 @font-face 规则中定义的常规字体面显示:

regular face display

然而,斜体文本在大多数用户代理中将使用从常规字体面合成倾斜的字形显示,因为没有定义单独的斜体面:

synthetic italics display

现在考虑一个定义了实际斜体面的家族:

@font-face { 
  font-family: BaskervilleFull; 
  src: url(baskerville-regular.woff2); 
} 

@font-face { 
  font-family: BaskervilleFull; 
  src: url(baskerville-italic.woff2); 
  font-style: italic; 
} 

第二个 @font-face 规则将字体资源 baskerville-italic.woff 定义为具有正常粗细、正常拉伸和斜体样式的字体。当显示斜体文本时,用户代理将使用此字体,因为它是斜体文本的最接近匹配。因此,文本将使用由字体设计师设计的字形显示,而不是使用从常规字体面合成的斜体字形:

real italics display

有关选择字体家族中特定字体面的过程的更多详细信息,请参见字体匹配部分。

字体可以公布它们与font-weightfont-width,和font-style的兼容范围。
@font-face { 
  font-family: Lastima; 
  src: url(lastima-varfont.woff2); 
  font-weight: 100 399; 
} 

上面的@font-face规则指示在font-weight值在 100 到 399 之间时应使用 lastima-varfont.woff。根据是否存在其他@font-face规则指定了 font-family: Lastimalastima-varfont.woff可能会用于 100-399 范围之外的font-weight值。有关更多详细信息,请参见§ 5 字体匹配算法

上面,多个@font-face规则可以组合成一个家族,跨越多个font-weightfont-width,和/或font-style范围:

@font-face { 
  font-family: Lastima; 
  src: url(lastima-varfont-lightrange.woff2); 
  font-weight: 100 399; 
} 
@font-face { 
  font-family: Lastima; 
  src: url(lastima-varfont-heavyrange.woff2); 
  font-weight: 400 700; 
} 

上面的@font-face规则指示当font-weight值在 100 到 399 之间时应使用 lastima-varfont-lightrange.woff,而当font-weight在 400 到 700 之间时应使用 lastima-varfont-heavyrange.woff。

4.4.1. 字体宽度: font-stretch 旧名称别名

由于历史原因,存在一个 font-stretch 描述符, 它是 旧名称别名,其功能与 font-width 完全相同。

4.5. 字符范围: unicode-range 描述符

名称: unicode-range
用于: @font-face
值: <urange>#
初始值: U+0-10FFFF
测试

此描述符定义了可能由声明的字体面支持的 Unicode 代码点集。描述符值是以逗号分隔的 Unicode 范围 (<urange>) 值列表。这些范围的并集定义了用于用户代理在决定是否为给定文本运行下载字体资源时的提示的代码点集。

每个 <urange> 值是由 "U+" 或 "u+" 前缀和以下列三种形式之一的代码点范围组成的 UNICODE-RANGE 记号。不符合这些形式之一的范围是无效的,并导致声明被忽略。

单个代码点(例如 U+416)
一个 Unicode 代码点,用一到六个十六进制数字表示
区间范围(例如 U+400-4ff)
用连字符分隔的两个 Unicode 代码点表示,表示范围的起始和结束代码点(含)
通配符范围(例如 U+4??)
通过尾随 '?' 字符指定的代码点集,表示任意十六进制数字

各个代码点使用与 Unicode 字符代码点对应的十六进制值编写。Unicode 代码点值必须在 0 到 10FFFF 之间。代码点的数字值是ASCII 不区分大小写的。对于区间范围,起始和结束代码点必须在上述范围内,并且结束代码点必须大于或等于起始代码点。

缺少首位数字的带有 '?' 的通配符范围(例如 "U+???")是有效的,相当于具有首位零数字的通配符范围(例如 "U+0???" = "U+0000-0FFF")。超出 Unicode 代码点范围的通配符范围是无效的。因此,尽管 UNICODE-RANGE 记号接受六个数字,但尾随 '?' 通配符字符的最大数量为五个。

unicode-range 描述符声明中的逗号分隔的 Unicode 范围列表中,范围可能会重叠。这些范围的并集定义了对应字体可以使用的代码点集。用户代理不得下载或使用超出此集合的代码点的字体。用户代理可以将范围列表规范化为表示相同代码点集但不同的列表。

相关字体可能不包含由 unicode-range 描述符定义的整个代码点集。当使用字体时,有效字符映射 是由 unicode-range 定义的代码点与字体的 字符映射 的交集。这允许作者以广泛的范围定义支持的范围,而不必担心底层字体支持的确切代码点范围。

4.5.1. 使用字符范围定义复合字体

对于相同的字体家族和样式描述符值,多个 @font-face 规则可使用不同的 Unicode 范围,来创建复合字体,将不同字体的字形混合用于不同的脚本。 这可以用于组合只包含单个脚本(例如拉丁文、希腊文、斯拉夫文)字形的字体,也可以作为一种将字体划分为常用字符和不常用字符的方式。 由于用户代理只会下载需要的字体,这有助于减少页面的带宽消耗。

如果一组 @font-face 规则的 Unicode 范围重叠且具有相同的字体家族和样式描述符值,则这些规则按照它们定义的逆序排列;最后定义的规则将在给定字符中首先被检查。

特定语言或字符的示例范围:

unicode-range: U+A5;
单个代码点,日元/人民币符号
unicode-range: U+0-7F;
基本 ASCII 字符的代码范围
unicode-range: U+590-5ff;
希伯来字符的代码范围
unicode-range: U+A5, U+4E00-9FFF, U+30??, U+FF00-FF9F;
日语汉字、平假名和片假名字符的代码范围,外加日元/人民币符号
英国广播公司(BBC)提供多种语言的新闻服务,许多语言并未在所有平台上得到良好支持。使用 @font-face 规则,BBC 可以为任何这些语言提供字体, 就像它通过手动字体下载已经做到的那样。

@font-face {
  font-family: BBCBengali;
  src: url(fonts/BBCBengali.woff) format("woff");
  unicode-range: U+00-FF, U+980-9FF;
}
技术文档通常需要大量符号。STIX 字体项目旨在为广泛的技术排版提供标准化支持。以下示例展示了一个为 Unicode 中许多数学和技术符号范围提供字形的字体:
@font-face {
  font-family: STIXGeneral;
  src: local(STIXGeneral), url(/stixfonts/STIXGeneral.otf);
  unicode-range: U+000-49F, U+2000-27FF, U+2900-2BFF, U+1D400-1D7FF;
}
该示例展示了作者如何用不同字体的字形覆盖日语字体中的拉丁字符。 第一个规则未指定范围,因此默认为整个范围。 第二个规则中指定的范围重叠,但因定义时间较晚而优先。
@font-face {
  font-family: JapaneseWithGentium;
  src: local(MSMincho);
  /* 未指定范围,默认为整个范围 */
}

@font-face {
  font-family: JapaneseWithGentium;
  src: url(../fonts/Gentium.woff);
  unicode-range: U+0-2FF;
}
考虑一个通过将拉丁文、日文和其他字符分成不同字体文件来优化带宽的字体家族:
/* 回退字体 - 大小:4.5MB */
@font-face {
  font-family: DroidSans;
  src: url(DroidSansFallback.woff);
  /* 未指定范围,默认为整个范围 */
}

/* 日文字形 - 大小:1.2MB */
@font-face {
  font-family: DroidSans;
  src: url(DroidSansJapanese.woff);
  unicode-range: U+3000-9FFF, U+ff??;
}

/* 拉丁文、希腊文、斯拉夫文及一些标点符号和符号 - 大小:190KB */
@font-face {
  font-family: DroidSans;
  src: url(DroidSans.woff);
  unicode-range: U+000-5FF, U+1e00-1fff, U+2000-2300;
}

对于简单的拉丁文文本,只会下载拉丁字符的字体:

body { font-family: DroidSans; }

<p>This is that</p>

在这种情况下,用户代理首先检查包含拉丁字符的字体的 unicode-range(DroidSans.woff)。由于所有字符均在 U+0-5FF 范围内,用户代理下载该字体并使用该字体呈现文本。

接下来,考虑使用箭头字符(⇨)的文本:

<p>This &#x21e8; that<p>

用户代理再次首先检查包含拉丁字符的字体的 unicode-range。由于 U+2000-2300 包含箭头代码点 (U+21E8),用户代理下载该字体。 然而,拉丁字体不包含此字符的匹配字形,因此字体匹配时使用的有效 unicode-range 不包括此代码点。接下来,用户代理评估日文字体。日文字体的 unicode-range(U+3000-9FFF 和 U+ff??)不包含 U+21E8,因此用户代理不会下载日文字体。 接下来考虑回退字体。回退字体的 @font-face 规则未定义 unicode-range,因此其值默认为所有 Unicode 代码点的范围。 用户代理下载回退字体并使用它呈现箭头字符。

4.6. 字体特性与变体:font-feature-settingsfont-variation-settings 描述符

名称: font-feature-settings
适用于: @font-face
值: normal | <feature-tag-value>#
初始值: normal
测试
名称: font-variation-settings
适用于: @font-face
值: normal | [ <string> <number>]#
初始值: normal
测试

这些描述符定义了在 @font-face 规则定义的字体渲染时适用的初始设置。它们不会影响字体选择。 值与下文定义的相应 font-feature-settingsfont-variation-settings 属性定义的值相同,但省略了 CSS-wide 关键字。当使用多个字体特性描述符、属性或变体时,可选地与命名实例一起使用, 对文本渲染的累积效果在 § 7 字体特性与变体解析 部分中详细说明。

这些描述符在 @font-face 规则表示的字体对象上设置特性和变体值,而不是在整个元素上。因此,在使用这些描述符时,由于 § 5.3 群组匹配,元素中的某些字形可能仅部分渲染了该特性。

4.7. 使用可变字体中的命名实例:font-named-instance 描述符

名称: font-named-instance
适用于: @font-face
值: auto | <string>
初始值: auto

如果 font-named-instance 描述符设置为 auto 以外的值,那么在 § 7 字体特性与变体解析 的适当阶段,将检查字体文件以查找字体中第一个具有本地化名称等于给定 <string> 的命名实例,规则见 § 5.1 本地化名称匹配。如果不存在这样的命名实例,则该描述符将被视为其值为 auto。否则,此命名实例的变体轴值将应用于 § 7 字体特性与变体解析 中的此位置。

例如,以下 @font-face 块将应用命名为 "Grotesque" 的实例,但会覆盖 "XHGT" 轴的值为 0.7。
@font-face {
  font-family: "AccuroVar";
  src: url("accurovar.otf") format("opentype");
  font-named-instance: "Grotesque";
  font-variation-settings: "XHGT" 0.7;
}

注意:由于 font-weightfont-widthfont-style 属性中提供的变体轴值在 font-named-instance 描述符的值之前应用,因此当需要命名实例时,无需更改这些属性的值。

4.8. 字体请求指南

4.8.1. 字体加载指南

@font-face 规则的设计目的是为了懒加载字体资源,仅在文档中使用时才下载字体。样式表可以包含多个 @font-face 规则定义的字体库,其中只有某些字体被实际使用;用户代理必须仅下载在给定页面的样式规则中被引用的那些字体。用户代理如果下载了所有定义在 @font-face 规则中的字体,而不考虑这些字体是否在页面中被使用,则被视为不符合规范。在字符回退的情况下,用户代理可以下载包含在给定文本运行的 font-family 计算值中的字体。

@font-face { 
  font-family: GeometricModern; 
  src: url(font.woff); 
}

p { 
  /* 页面中有 p 元素时将下载字体 */ 
  font-family: GeometricModern, sans-serif; 
}

h2 { 
  /* 即使本地存在 Futura 字体,也可能为 h2 元素下载字体 */ 
  font-family: Futura, GeometricModern, sans-serif; 
} 

在文本内容加载后可下载字体未能及时提供的情况下,用户代理必须根据该 font-display 描述符渲染文本。如果字体下载失败,用户代理必须让文本可见显示。建议作者在其字体列表中使用与可下载字体的度量标准接近的后备字体,以尽可能避免页面大范围的重新排版。

4.8.2. 字体获取要求

要根据选定的 <url> url@font-face rule 获取字体,请 fetch url,样式表为 rule父 CSS 样式表,目标为 "font",CORS 模式为 "cors",processResponse 的步骤如下,给定 response res 和 null、失败或字节流 stream
  1. 如果 stream 为 null,则返回。

  2. 根据类型从 stream 加载字体。

注意: 对作者的影响是,字体通常不会跨域加载,除非作者采取特定步骤允许跨域加载。站点可以通过 Access-Control-Allow-Origin HTTP 头显式允许跨站加载字体数据。对于其他方案,除了 fetch 算法允许的跨域加载外,不定义或要求显式机制。

测试
以下示例中,假设文档位于 https://example.com/page.html,所有链接指向由用户代理支持的有效字体资源。

以下 src 描述符值定义的字体将被加载:

/* 同源 (即域、协议、端口与文档匹配) */src: url(fonts/simple.woff);

/* 没有重定向的数据 url 被视为同源 */
src: url("data:application/font-woff;base64,...");

/* 跨域,不同域名 */
/* Access-Control-Allow-Origin 响应头设置为 '*' */
src: url(http://another.example.com/fonts/simple.woff);

以下 src 描述符值定义的字体将无法加载:

/* 跨域,不同协议 *//* 响应中无 Access-Control-xxx 头 */
src: url(http://example.com/fonts/simple.woff);

/* 跨域,不同域名 */
/* 响应中无 Access-Control-xxx 头 */
src: url(http://another.example.com/fonts/simple.woff);

4.9. 控制每个字体的显示:font-display 描述符

font-display 描述符用于 @font-face 规则,确定字体的显示方式,基于它何时被下载并准备使用。

名称: font-display
适用规则: @font-face
值: auto | block | swap | fallback | optional
初始值: auto
测试

注意: 对于所有这些值,用户代理可以使用稍微不同的持续时间,或更复杂的行为,提供更有用的用户体验。用户还可以覆盖作者选择的行为,例如强制所有字体具有 0s 阻塞期

auto
字体显示策略由用户代理定义。

注意: 许多浏览器的默认策略类似于 block

block
为字体赋予一个短的 阻塞期(建议为 3s)和一个无限的 交换期

注意: 换句话说,浏览器最初会绘制“不可见”文本,如果字体未加载,但一旦字体加载,就会立即替换字体。

此值仅应在渲染某个字体对于页面可用性至关重要的情况下使用,且只适用于少量文本。

例如,设计不良的“图标字体”可能会将“⎙”与某个无关的字符(如“P”)关联,因此如果用回退字体显示这些文本,页面上会出现混乱的字母,而不是所需的图标。在这种情况下,临时空白比使用回退字体更好。

然而,最终仍会使用回退字体,因为相比于永远无法显示链接等,页面上散布着混乱的字母要好一些。

swap
为字体赋予一个极短的 阻塞期(建议为 100ms 或更短)和一个无限的 交换期

注意: 换句话说,浏览器会立即用回退字体绘制文本,如果字体未加载,但一旦字体加载,就会替换。

当在某个特定字体中渲染文本非常重要,但用任何字体都能传达正确的信息时,应该使用这个值。此值应仅用于少量文本。

例如,某网站有一个自定义字体用于渲染他们的 logo,正确渲染这个 logo 对于品牌很重要,但用任何字体显示 logo 至少不会造成混淆。
fallback
为字体赋予一个极短的 阻塞期(建议为 100ms 或更短)和一个短的 交换期(建议为 3s)。

注意: 换句话说,浏览器最初会用回退字体绘制文本,但一旦字体加载,就会替换字体。然而,如果时间过长,回退字体将用于页面的剩余部分。

此值适用于正文文本,或其他文字,在这些场合使用选定字体是有用且期望的,但用户看到回退字体也能接受。此值适合用于大段文本。

例如,在大段正文文本中,最重要的是让文本尽快呈现,以便用户可以立即开始阅读。此外,一旦用户开始阅读,文本突然“移动”以替换字体将非常令人分心和烦恼。
optional
如果字体可以“立即”加载(即可以用于文本的“首次绘制”),则使用该字体。

否则,字体将被视为其 阻塞期交换期 在加载完成之前已过期。如果未使用字体,用户代理可以选择终止字体下载,或以非常低的优先级下载字体。如果用户代理认为有用,也可以避免启动字体下载,直接使用回退字体。

optional 字体决不能导致页面布局在加载后“跳动”。用户代理可以选择稍微延迟元素的渲染,以便从可能较慢的本地缓存中加载字体,但一旦文本已经用回退字体绘制到屏幕上,在页面的剩余时间内都不会再使用 optional 字体。

此值适用于正文文本或其他文字,在这些情况下,选定字体纯粹是装饰性的“锦上添花”。它应该在第一次访问网页时快速渲染比等待更长时间看到完美呈现更重要时使用。

例如,正文文本在浏览器默认字体中是完全可读的,尽管可下载字体面貌更好,且更符合网站美学。首次访问网站的用户通常更关心网站是否快速可用,而不是页面的精细显示,optional 提供了良好的表现。

如果他们稍后再次访问,所需的字体可能已经下载完成,提供“预期”的体验,而不会延迟首次或后续访问的速度。

对于非常慢的连接,用户可能永远无法获得“预期”的体验,但 optional 确保他们可以实际使用网站,而不是因为加载时间过长而放弃。

为了增加 optional 字体在渲染文本时可用的可能性,建议用户代理使用启发式方法使其更快访问或判断何时值得延迟渲染某些文本,例如检查字体是否在 HTML 中预加载,或将文件从较慢的缓存移动到较快的内存缓存中(在样式表中看到字体之前)。

然而,作者不能依赖这些启发式方法;必须理解,optional 可能导致字体永远不会被使用。如果需要更高的字体使用保证,作者应考虑使用 fallback 值。

4.9.1. 通过 @font-feature-values 控制字体族的显示

font-display 描述符用于 @font-feature-values,用于设置字体族的显示方式,设定针对相同字体族的 @font-face 规则的 "默认" font-display 值。当 @font-face 规则中省略了 font-display 时,用户代理将使用针对相关字体族通过 @font-feature-values 设置的 font-display 值,否则默认为 font-display: auto

此机制可用于为整个字体族设置默认显示策略,并使开发人员能够为他们无法直接控制的 @font-face 规则设置显示策略。例如,当字体由第三方字体铸造厂提供时,开发人员无法控制 @font-face 规则,但仍然能够为提供的字体族设置默认的 font-display 策略。为整个字体族设置默认策略还可以避免 "赎金字条效应"(即字体面不匹配),因为显示策略会应用于整个字体族。

名称: font-display
适用规则: @font-feature-values
值: auto | block | swap | fallback | optional
初始值: auto

4.10. 默认字体语言覆盖:font-language-override 描述符

名称: font-language-override
适用规则: @font-face
值: normal | <string>
初始值: normal

此描述符定义了在渲染由 @font-face 规则定义的字体时应用的初始设置。它不影响字体选择。值与下面定义的 font-language-override 属性相同,除了省略了 inherit 值。当使用多个字体特性描述符、属性或变体时,文本渲染的累计效果详见 § 7 字体特性和变体解析

4.11. 默认字体度量覆盖:ascent-overridedescent-overrideline-gap-override 描述符

名称: ascent-override
适用规则: @font-face
值: normal | <percentage [0,∞]>
初始值: normal
Tests
名称: descent-override
适用规则: @font-face
值: normal | <percentage [0,∞]>
初始值: normal
Tests
名称: line-gap-override
适用规则: @font-face
值: normal | <percentage [0,∞]>
初始值: normal

ascent-overridedescent-overrideline-gap-override 描述符分别定义了字体的 ascent metricdescent metricline gap metric

当描述符值为 normal 时,相关度量值直接从字体文件中获取。

注意: 用户代理可能从字体文件的不同位置提取度量数据,这将导致文本布局的不同。

当描述符值为百分比时,相关的度量值按使用的字体大小乘以给定的百分比解析。负值在解析时无效。

百分比根据不同元素的字体大小进行解析。
@font-face {
  font-family: overridden-font; 
  ascent-override: 50%; 
  ...
}

<span style="font-family: overridden-font; font-size: 20px;">
  Outer span content
  <span style="font-size: 150%;">Inner span content</span>
</span>

外部 span 使用 ascent 值为 10px,而内部 span 使用的是 15px。

我们可以覆盖本地回退字体的度量值,使其与主字体匹配,这样在从回退字体切换到主字体时可以减少布局的偏移。
@font-face {
  font-family: cool-web-font; 
  src: url("https://example.com/font.woff"); 
}

@font-face { 
  font-family: fallback-to-local; 
  src: local(Some Local Font); 
  /* 覆盖度量值以匹配 cool-web-font */ 
  ascent-override: 125%; 
  descent-override: 25%; 
  line-gap-override: 0%; 
}

<div style="font-family: cool-web-font, fallback-to-local">Title goes here</div> 
<img src="https://example.com/largeimage" alt="一个不想要偏移的大图">

当用户代理加载完成并切换为使用 web 字体时,图像不会发生垂直偏移。

5. 字体匹配算法

下面的算法描述了如何将字体与单独的文本运行关联起来。对于运行中的每个字符,都会选择一个字体系列,并为该字符选择包含字形的特定字体样式。

可供字体匹配算法使用的已安装字体集合明确未定义。

默认的已安装字体集合会根据用户代理、平台和区域的不同而有所变化;对于用户能够自定义哪些已安装字体可用于渲染网页以及这些字体(如果有)映射到哪些通用字体系列,这一点至关重要。

用户代理可以选择将所有已安装的字体暴露给网页,无论该字体是如何安装的;这样做可能会为主要语言不受操作系统自带字体支持的用户带来良好的国际化属性。

用户代理也可以选择不暴露任何用户安装的字体,以帮助保护网络隐私;因为用户安装字体集合通常被用作跟踪用户的向量,跨网站追踪用户。用户可以根据需要添加或删除该字体集合中的字体。

用户代理也可以选择混合方法,初始暴露某些用户安装的字体以支持国际化,但不暴露其他字体。同样,用户可以自定义此起始集合。

用户代理应该根据国际化和隐私之间的平衡,做出关于默认暴露哪些字体的明智决策。用户代理还应该提供方便的方式,供用户根据他们的具体需求添加和删除字体。

测试

5.1. 本地化名称匹配

某些字体文件格式允许字体样式携带特定字符串的多个本地化版本(例如,字体系列名称或命名实例)。用户代理必须能够识别并正确匹配所有这些名称,无论底层平台的本地化情况、使用的系统 API 或文档编码如何。

例如,对于下列字体,每个字体,作者都可以在 font-family 属性中使用拉丁名称或本地化名称,并且在所有系统上结果都是相同的:
本地化字体系列名称示例
本地化字体系列名称

用户代理必须不区分大小写地匹配这些名称,使用 Unicode 规范中概述的“默认无大小写匹配”算法 [UNICODE]。该算法详述于第 3.13 节“默认大小写算法”。具体而言,算法必须在不规范化相关字符串且不应用任何语言特定调整的情况下进行。该算法指定的大小写折叠方法使用 Unicode 字符数据库的 CaseFolding.txt 文件中状态字段为“C”或“F”的大小写映射。

注意: 对于作者来说,这意味着字体系列名称的匹配是大小写不敏感的,无论这些名称存在于平台字体中,还是样式表中的 @font-face 规则中。作者应确保名称的字符序列与实际的字体系列名称一致,尤其是在使用合并字符(如变音符号)时。例如,包含小写字母 a(U+0061)后跟合并圆环符号(U+030A)的系列名称不会匹配一个外观相同但使用预组合的小写字母 a-ring 字符(U+00E5)而非合并序列的名称。

注意: 实现者应注意验证给定的无大小写字符串比较实现是否使用了该精确算法,且不要假设给定平台的字符串匹配例程遵循此算法,因为许多这些例程具有特定区域的行为,或使用某种程度的字符串规范化。

5.2. 字体样式匹配

为给定文本中的字符选择字体的过程包括遍历 font-family 属性中命名的字体系列,基于其他字体属性选择合适的字体样式,然后确定是否存在该字符的字形。这是通过使用字体的 字符映射 来完成的,该数据将字符映射到该字符的默认字形。如果字体的 字符映射 中包含字符,并且(2)如果包含的脚本需要,则提供该字符的成形信息,则认为该字体 支持该字符。

某些旧版字体可能会在其 字符映射 中包含某些字符,但缺乏正确渲染包含该字符的文本所需的成形信息(例如 OpenType 布局表Graphite 表)。

由基础字符后跟合并字符序列组成的代码点序列稍有不同,详见下文中的 簇匹配 部分。

对于此过程,给定字体系列的 默认样式 定义为所有字体样式属性均设置为其初始值时将选择的样式。

  1. 使用给定元素的计算字体属性值,用户代理从 font-family 属性指定的第一个系列名称开始。

  2. 如果系列名称是通用系列关键字,用户代理将查找应使用的合适字体系列名称。用户代理可以根据包含元素的语言或字符的 Unicode 范围选择通用字体系列。

  3. 对于其他系列名称,用户代理尝试在通过 @font-face 规则定义的字体中找到该系列名称,然后在可用的已安装字体中查找(这可能包括字体别名),如上文 § 5.1 本地化名称匹配 中所述。如果通过 @font-face 规则定义的字体资源不可用或包含无效的字体数据,则应将该样式视为不在系列中。如果通过 @font-face 规则定义的系列没有任何样式,应将该系列视为不存在;在这种情况下,不能匹配具有相同名称的平台字体。

  4. 如果发生字体系列匹配,用户代理会收集该系列中的字体样式集,然后根据以下顺序使用其他字体属性将该集缩小为单一样式。此过程中可能包含可以支持一系列 font-widthfont-stylefont-weight 属性的字体。在这种情况下,算法会继续进行,好像每个支持的组合值是集合中的唯一字体。如果该算法最终选择了这样的字体,则必须在任何布局或渲染发生之前应用 font-widthfont-stylefont-weight 的特定值。值的应用必须在 应用字体匹配变体步骤中执行,详细内容见 § 7 字体功能和变体解析。通过 @font-face 规则定义的、字体描述符值相同但 unicode-range 值不同的字体样式组在此步骤中被视为一个 复合样式

    测试
    1. font-width 尝试优先匹配。如果某个字体不具备变化宽度值的概念,其宽度值将根据 属性定义 中的表进行映射。如果匹配集合包含具有所需 font-width 值的样式,则不包含所需宽度值的样式将从匹配集合中移除。如果没有样式包含所需的值,将根据以下规则选择一个宽度值:

      • 如果所需的宽度值小于或等于 100%,则首先检查低于所需宽度值的宽度,按降序排列,然后按升序检查高于所需宽度值的宽度,直到找到匹配项为止。

      • 否则,按升序检查高于所需宽度值的宽度,然后按降序检查低于所需宽度值的宽度,直到找到匹配项为止。

      一旦通过此过程确定了最接近的匹配宽度,不包含该确定宽度的样式将从匹配集合中移除。

      该搜索算法可以视为距离函数,其中选择字体家族中存在的最小距离值,未包含该值的所有字体将被排除。

      考虑一个包含三个字体的字体家族,分别命名为 A、B 和 C,每个字体都有与 font-width 描述符相关的支持范围。如果某个元素的样式为 "font-width: 125%",则搜索算法可以可视化为如下:

      algorithm

      上图展示了字体 A、B 和 C 所支持的宽度范围。正如你所看到的,由于字体 B 包含整个家族中的最小宽度值,算法将选择字体 B。但是,如果字体 B 被从家族中移除,字体 C 将包含家族中最低的距离,因此将被选中。

      类似于 前一个示例,下面是样式为 "font-width: 75%" 的元素的概念距离图:

      distance graph

      正如你所看到的,由于字体 B 包含整个家族中最小的宽度值,因此算法将选择字体 B。但是,如果字体 B 被从家族中移除,字体 A 将包含家族中最低的距离,因此将被选中。

    2. font-style 接下来尝试匹配(参见 § 5.2 字体样式匹配)。如果字体不具备变化倾斜角度或意大利体强度的概念,其样式将根据 font-style 属性定义中的描述进行映射。

      如果 font-style 的值为 italic

      1. 如果匹配集合包含具有 italic 值的样式,则不包含所需斜体映射值的样式将从匹配集合中移除。

      2. 否则,按升序检查高于所需斜体值的斜体值,然后按降序检查低于所需斜体值的斜体值,直到达到 0。此阶段仅检查正值。

      3. 如果未找到匹配项,按升序检查大于或等于 11 度的斜角值,然后按降序检查低于 11 度的斜角值,直到达到 0。此阶段仅检查正值。

        应该将斜角优于常规的阈值设定为低于平均角度。

      4. 如果未找到匹配项,按降序检查小于或等于 0 的斜体值,直到找到匹配项为止。

      5. 如果未找到匹配项,按降序检查小于或等于 0 度的斜角值,直到找到匹配项为止。

        类似于 前一个示例,下面是样式为 "font-style: italic" 的元素的概念距离图:

        distance graph

        正如你所看到的,由于字体 D 包含整个家族中的最小斜体值,算法将选择字体 D。但是,如果字体 D 被从家族中移除,字体 E 将包含家族中最低的距离,因此将被选中。如果字体 E 被移除,算法将选择字体 C。如果字体 C 被移除,算法将不会立即选择字体 B;此时将参考斜角值并可能选择斜角值。但是,如果未选择任何斜角值,算法将选择字体 B,接着是字体 A。

      如果 font-style 的值为 oblique 且请求的角度大于或等于 11 度:

      1. 如果匹配集合包含具有 oblique 值的样式,不包含所需斜角值的样式将从匹配集合中移除。

      2. 否则,按升序检查高于所需斜角值的斜角值,然后按降序检查低于所需斜角值的斜角值,直到达到 0。此阶段仅检查正值。

      3. 对于具有 slnt 轴的可变字体,通过设置 slnt 值并指定斜角值来进行匹配。否则,如果 font-synthesis-style 的值为 auto,则通过几何剪切生成指定的斜角值,产生回退匹配。

      4. 如果未找到匹配项,按升序检查大于或等于 1 的斜体值,然后按降序检查低于 1 的斜体值,直到达到 0。此阶段仅检查正值。

      5. 如果未找到匹配项,按降序检查小于或等于 0 度的斜角值,直到找到匹配项为止。

      6. 如果未找到匹配项,按降序检查小于或等于 0 的斜体值,直到找到匹配项为止。

        类似于 前一个示例,下面是样式为 "font-style: oblique 40deg" 的元素的概念距离图:

        distance graph

        正如你所看到的,由于字体 D 包含整个家族中的最小斜角值,因此算法将选择字体 D。但是,如果字体 D 被从家族中移除,字体 E 将包含家族中最低的距离,因此将被选中。如果字体 E 被移除,算法将选择字体 C。如果字体 C 被移除,算法将不会立即选择字体 B;此时将参考斜体值并可能选择斜体值。但是,如果未选择任何斜体值,算法将选择字体 B,接着是字体 A。

      如果 font-style 的值为 oblique 且请求的角度大于或等于 0 度且小于 11 度,

      1. 如果匹配集合包含具有 oblique 值的样式,则不包含所需斜角值的样式将从匹配集合中移除。

      2. 否则,按降序检查低于所需斜角值的斜角值,直到达到 0 度,然后按升序检查高于所需斜角值的斜角值。此阶段仅检查正值的斜角值。

      3. 对于具有 slnt 轴的可变字体,通过设置 slnt 值并指定斜角值来进行匹配。否则,如果 font-synthesis-style 的值为 auto,则通过几何剪切生成指定的斜角值,产生回退匹配。

      4. 如果未找到匹配项,按降序检查小于 1 的斜体值,直到达到 0 度,然后按升序检查大于 1 的斜体值。此阶段仅检查正值的斜体值。

      5. 如果未找到匹配项,按降序检查小于或等于 0 度的斜角值,直到找到匹配项为止。

      6. 如果未找到匹配项,按降序检查小于或等于 0 的斜体值,直到找到匹配项为止。

      类似于 前一个示例,下面是样式为 "font-style: oblique 13deg" 的元素的概念距离图:

      distance graph

      正如你所看到的,由于字体 D 包含整个家族中的最小斜角值,因此算法将选择字体 D。但是,如果字体 D 被从家族中移除,字体 C 将包含家族中最低的距离,因此将被选中。如果字体 C 被移除,算法将选择字体 E。如果字体 E 被移除,算法将不会立即选择字体 B;此时将参考斜体值并可能选择斜体值。但是,如果未选择任何斜体值,算法将选择字体 B,接着是字体 A。

      如果 font-style 的值为 oblique 且请求的角度小于 0 度且大于 -11 度,请按照 上述步骤 执行,但取反这些值和相反的方向。如果 font-style 的值为 oblique 且请求的角度小于或等于 -11 度,请按照 上述步骤 执行,但取反这些值和相反的方向。

      如果 font-style 的值为 normal

      1. 按升序检查大于或等于 0 的斜角值。

      2. 如果未找到匹配项,按升序检查大于或等于 0 的斜体值。

      3. 如果未找到匹配项,按降序检查小于 0 度的斜角值,直到找到匹配项为止。

      4. 如果未找到匹配项,按降序检查小于 0 的斜体值,直到找到匹配项为止。

      类似于 前一个示例,下面是样式为 "font-style: normal" 的元素的概念距离图:

      distance graph

      正如你所看到的,由于字体 C 包含整个家族中的最小斜角值,因此算法将选择字体 C。但是,如果字体 C 被从家族中移除,算法将不会立即选择字体 B;此时将参考斜体值并可能选择斜体值。但是,如果未选择任何斜体值,算法将选择字体 B,接着是字体 A。

      如果在上述搜索中找到了斜角值,则所有未包含该斜角值的样式都将从匹配集合中排除。否则,如果找到了斜体值,则所有未包含该斜体值的样式都将从匹配集合中排除。

      用户代理不需要区分斜体和斜角字体。在这种情况下,用户代理通过将斜体值和斜角值映射到一个共同的尺度上来执行 font-style 匹配步骤。该映射的确切性质未定义,然而,斜体值 1 必须映射到与斜角值 11 度相同的值。在通过 @font-face 规则定义的字体家族中,斜体和斜角样式必须通过 font-style 描述符的值来区分。

      对于缺少斜体或斜角样式的家族,用户代理可以创建人工斜角样式,如果 font-synthesis 属性的值允许这样做。

    3. font-weight 接下来匹配。如果字体没有任何不同权重值的概念,则其权重值会根据 属性定义中的列表进行映射。如果使用了更粗/更细的相对权重值,则根据继承的权重值计算有效权重值,如 font-weight 属性定义中所述。如果在执行上述步骤后匹配集包含具有所需 font-weight 值的样式,则不包含所需权重值的样式将从匹配集中移除。如果没有样式包含所需的值,则根据以下规则选择权重值:

      • 如果所需的权重值在 400 到 500 之间(含),首先按升序检查大于或等于目标权重的权重值,直到 500 被命中并检查,然后按降序检查小于目标权重的权重值,再按升序检查大于 500 的权重值,直到找到匹配项。

      • 如果所需的权重值小于 400,首先按降序检查小于或等于所需权重的权重值,然后按升序检查大于所需权重的权重值,直到找到匹配项。

      • 如果所需的权重值大于 500,首先按升序检查大于或等于所需权重的权重值,然后按降序检查小于所需权重的权重值,直到找到匹配项。

      类似于 前一个示例,这是一个样式为 "font-weight: 400" 的元素的概念距离图:

      distance graph

      如你所见,由于字体 B 包含整个家族中最小的距离,算法将选择字体 B。但是,如果字体 B 被从家族中移除,则字体 C 将包含家族中最低的距离,因此将被选中。如果字体 C 被移除,则选择 D,然后是字体 A 和 E。

      类似于 前一个示例,这是一个样式为 "font-weight: 450" 的元素的概念距离图:

      distance graph

      如你所见,由于字体 C 包含整个家族中最小的距离,算法将选择字体 C。但是,如果字体 C 被从家族中移除,则字体 D 将包含家族中最低的距离,因此将被选中。如果字体 D 也被移除,则选择 B,然后是字体 A 和 E。

      类似于 前一个示例,这是一个样式为 "font-weight: 500" 的元素的概念距离图:

      distance graph

      如你所见,由于字体 D 包含整个家族中最小的距离,算法将选择字体 D。但是,如果字体 D 被从家族中移除,则字体 B 将包含家族中最低的距离,因此将被选中。如果 B 被移除,则选择 C,然后是字体 B、A 和 E。

      类似于 前一个示例,这是一个样式为 "font-weight: 300" 的元素的概念距离图:

      distance graph

      如你所见,由于字体 B 包含整个家族中最小的距离,算法将选择字体 B。但是,如果字体 B 被从家族中移除,则字体 A 将包含家族中最低的距离,因此将被选中。如果 A 被移除,则选择 C。

      一旦通过此过程确定了最接近的匹配权重,未包含此确定权重的样式将从匹配集中移除。

      注意:[CSS-FONTS-3] 和本规范之间,font-weight 属性的动画行为有细微变化。以前,font-weight 的插值值会被四舍五入到最接近的 100 倍数,并在这些舍入后的值上运行字体匹配算法。在本规范中,字体匹配算法可以接受任何值,因此不进行四舍五入。由于字体匹配算法的非连续性,导致了这种小的行为变化。

    4. font-size 必须在用户代理相关的容差范围内匹配。(通常,可伸缩字体的大小会四舍五入到最接近的整个像素,而位图字体的容差可能高达 20%。)进一步的计算,例如其他属性中的 em 值,是基于使用的 font-size 值,而不是指定的值。

    请注意,在执行上述步骤后,匹配集中可能会剩下多个字体。如果是这样,用户代理必须从匹配集中选择一个字体,并继续这些步骤。不同用户代理和操作系统平台选择字体的方式可能不同;然而,在同一文档中的两个元素之间,选择的字体不应有所不同。

  5. 如果匹配到的字体是通过 @font-face 规则定义的,用户代理必须使用以下程序来选择单个字体:

    1. 如果字体资源尚未加载,并且 unicode-range 描述符值定义的字符范围包含所查询的字符,则加载字体。

    2. 下载后,如果 有效字符映射 支持所查询的字符,则选择该字体。

    当匹配的字体是一个 复合字体 时,用户代理必须按照上述程序处理复合字体中的每一个样式,并以 @font-face 规则定义的逆序进行。

    在下载字体期间,用户代理必须选择等待字体下载完成,或者在下载完成前使用替代的字体度量进行渲染,随后在字体下载完成后再次渲染。

  6. 如果没有匹配的字体样式存在,或者匹配的样式不包含所需字符的字形,则选择下一个字体系列名,并重复之前的三个步骤。其他字体样式中的字形不予考虑。唯一的例外是,如果默认样式支持给定的字形,并且 font-synthesis 属性允许合成,则用户代理可以选择合成版本的斜体。例如,如果斜体样式不支持阿拉伯字母,则可能会使用常规字体的合成斜体版本。

  7. 如果没有更多的字体系列可供评估,且没有找到匹配的字体样式,则用户代理执行 安装字体回退 程序,以找到字符的最佳匹配字体。此程序的结果可能因用户代理而异。

  8. 如果任何字体都无法显示特定字符,用户代理应通过某种方式指示无法显示字符,例如显示缺失字形的符号表示(例如使用 最后手段字体),或使用默认字体中的缺失字符字形。

允许对该过程进行优化,只要实现表现得像是严格遵循了该算法。匹配按明确的顺序进行,以确保在给定相同的可用字体和渲染技术的情况下,结果在各用户代理之间尽可能保持一致。

首个可用字体, 例如在定义 字体相对长度(如 ex)或 line-height 属性时使用,定义为第一个不会被 unicode-range 排除字符 U+0020(空格)的字体,在 font-family 列表中选择(如果没有可用字体,则使用用户代理的默认字体)。

直接通过字体系列名引用的已安装字体,而不是通过 @font-face 规则引用的字体,被认为具有覆盖整个 Unicode 代码空间的 unicode-range

测试

注意:无论该字体是否实际具有空格字符的字形,这一点并不重要。

5.3. 簇匹配

当文本包含组合符号等字符时,理想情况下,基础字符和符号应使用相同的字体渲染,这可以确保符号的正确位置。因此,簇的字体匹配算法比单独匹配单个字符的常规情况更为专业。对于包含变体选择器的序列,它们指示要用于给定字符的精确字形,用户代理始终尝试 已安装字体回退 以找到合适的字形,然后再使用基础字符的默认字形。

包含组合符号或其他修饰符的代码点序列称为字形簇(参见 [CSS3TEXT][UAX29] 获取更完整的描述)。对于包含基础字符 b 和组合字符序列 c1, c2… 的簇,整个簇按以下步骤匹配:

  1. 对于字体列表中的每个系列,使用前一节中定义的样式选择规则选择一个字体样式。
    1. 如果序列 b + c1 + c2 … 中的所有字符都被该字体完全支持,则为该序列选择此字体。
    2. 如果多个代码点的序列在规范上等同于单个字符,并且字体 支持该字符,则为该序列选择此字体,并为整个簇使用与规范等效字符相关的字形。
  2. 如果在步骤 1 中没有在字体列表中找到字体:
    1. 如果 c1 是一个变体选择器,系统回退必须被使用以找到支持整个 b + c1 序列的字体。如果系统上没有字体 支持整个序列,则使用常规匹配单个字符的过程来匹配单个字符 b,并忽略变体选择器。注意:包含多个变体选择器的序列必须被视为编码错误,后续的选择器必须被忽略。[UNICODE]
    2. 否则,用户代理可以选择使用已安装字体回退匹配支持整个簇的字体。
  3. 如果在步骤 2 中没有找到字体,则使用步骤 1 的匹配序列来确定由字体列表中的字体完全 支持 的最长序列,并尝试使用单个字符的匹配规则分别匹配其余的组合字符。

5.4. 字符处理问题

CSS 字体匹配始终针对包含 Unicode 字符的文本运行进行 [UNICODE],因此使用传统编码的文档在匹配字体之前被假定已进行转码。对于同时包含传统编码和 Unicode 字符映射的字体,传统编码的字符映射内容不得对字体匹配过程的结果产生影响。

字体匹配过程不假定文本运行处于标准化或非标准化形式(详情请参见 [CHARMOD-NORM])。字体可能只支持预组合形式,而不支持由基础字符加组合符号构成的分解序列。作者在选择字体时应始终根据其内容进行调整,包括该内容是否包含标准化或非标准化的字符流。

如果给定字符是私人使用区 Unicode 代码点,用户代理必须只匹配 font-family 列表中非通用系列名称的字体。 如果 font-family 列表中命名的系列没有包含该代码点的字形,用户代理必须显示某种形式的缺失字形符号,而不是尝试为该代码点使用 已安装字体回退。在匹配替换字符 U+FFFD 时,用户代理可以跳过字体匹配过程并直接显示某种形式的缺失字形符号,而不需要显示通过字体匹配过程选择的字体中的字形。

通常,给定系列的字体将具有相同或类似的 字符映射。这里概述的过程旨在处理甚至包含面部特征高度不同的 字符映射 的字体系列。然而,作者应注意,使用此类系列可能会导致意外结果。

测试

6. 字体功能属性

现代字体技术支持多种高级排版和特定语言的字体功能。利用这些功能,单个字体可以提供广泛的字形,包括连字、上下文和样式替代、表格和旧式数字、小型大写字母、自动分数、花饰和特定语言的替代字符。为了让作者能够控制这些字体功能,font-variant 属性得到了扩展。它现在作为一组属性的简写,用于控制样式字体功能。

6.1. 字形选择和定位

本节为非规范性内容

用于显示拉丁文本的简单字体使用非常基本的处理模型。字体包含一个 字符映射,将每个字符映射到该字符的字形。后续字符的字形只需一个接一个地放置在文本运行中。现代字体格式(如 OpenType 和 AAT(Apple 高级排版))使用更丰富的处理模型。给定字符的字形不仅可以根据字符本身的代码点来选择和定位,还可以根据相邻字符以及文本启用的语言、脚本和功能来选择。字体功能可能是某些脚本所必需的,或推荐默认启用的,或者可能是作者控制下使用的样式功能。字体选择和定位发生在文本处理操作的总体顺序中的位置(例如文本转换、文本方向和文本对齐)在 CSS 文本 3 § A 文本处理操作顺序 中有所描述。

有关 OpenType 字体字形处理的详细描述,请参见 [WINDOWS-GLYPH-PROC]

样式字体功能可以分为两大类:一类影响字形形状与周围上下文的和谐性,如字距调整和连字功能;另一类则影响形状选择,如小型大写字母、下标/上标和替代功能。

下面列出的 font-variant 子属性用于控制这些样式字体功能。它们不控制用于显示某些脚本的必需功能,例如用于显示阿拉伯文或印度语文本的 OpenType 功能。它们影响字形选择和定位,但不影响字体选择(除非为了兼容 CSS 2.1 而需要)。

为了确保跨用户代理的一致行为,单独属性的等效 OpenType 属性设置是规范性的。当使用其他字体格式时,应该将这些设置作为指导,以将 CSS 字体功能属性值映射到特定的字体功能。

6.2. 特定语言显示

OpenType 还支持特定语言的字形选择和定位,以便在语言规定特定显示行为的情况下正确显示文本。许多语言共用一种书写系统,但某些字母的形状在不同语言之间可能有所不同。例如,某些西里尔字母在俄语文本中与在保加利亚语中的形状不同。在拉丁文本中,通常将“fi”显式渲染为没有“i”上的点的连字。然而,在如土耳其语等同时使用带点和无点“i”的语言中,不使用该连字或使用包含“i”上的点的专用版本很重要。

测试

下面的示例展示了基于西班牙语、意大利语和法语正字法中的风格传统的特定语言变化:

特定语言形式,西班牙语
特定语言形式,意大利语
特定语言形式,法语

如果根据 文档语言 规则已知元素的内容语言,用户代理需要根据内容语言 推断 OpenType 语言系统,并在使用 OpenType 字体选择和定位字形时使用该系统。如果已明确指定了书写系统,则必须优先于由内容语言暗示的习惯系统。

对于 OpenType 字体,在某些情况下可能需要显式声明要使用的 OpenType 语言,例如当显示某种使用另一种语言的排版惯例的语言文本时,或者当字体未明确支持某种语言但支持与该语言共享常见排版惯例的语言时。font-language-override 属性用于此目的。

6.3. 字距调整:font-kerning 属性

名称: font-kerning
值: auto | normal | none
初始值: auto
适用范围: 所有元素和文本
继承性:
百分比: 不适用
计算值: 按指定计算
规范顺序: 按语法规则
动画类型: 离散型
测试

字距调整是对字形间距的上下文调整。该属性控制度量字距调整,利用字体中包含的调整数据进行调整。

auto
指定由用户代理决定是否应用字距调整
normal
指定应用字距调整
none
指定不应用字距调整

对于不包含字距调整数据的字体,此属性不会有任何可见效果。使用 OpenType 字体渲染时,[OPENTYPE] 规范建议默认启用字距调整。当启用字距调整时,相关的 OpenType 字距调整功能将启用(对于水平排版模式和竖直排版中的侧向排版,启用 kern 功能;对于正直排版中的竖直排版模式,启用 vkrn 功能)。用户代理还必须支持仅通过 kern 字体表中的数据支持字距调整的字体,如 OpenType 规范中详细说明的那样。如果定义了letter-spacing 属性,字距调整被视为默认间距的一部分,并且字距调整是在应用字距调整后进行的。

当设置为 auto 时,用户代理可以根据多个因素决定是否应用字距调整:文本大小、脚本或其他影响文本处理速度的因素。希望获得正确字距调整的作者应使用 normal 来显式启用字距调整。同样,一些作者可能希望在性能比外观精度更重要的情况下禁用字距调整。然而,在设计良好的现代实现中,字距调整的使用通常不会对文本渲染速度产生较大影响。

6.4. 连字:font-variant-ligatures 属性

名称: font-variant-ligatures
值: normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ]
初始值: normal
适用范围: 所有元素和文本
是否继承:
百分比: 不适用
计算值: 按指定
规范顺序: 按语法规则
动画类型: 离散
测试

连字和上下文形式是通过组合字形来生成更和谐的形式的方法。

<common-lig-values>        = [ common-ligatures | no-common-ligatures ]
<discretionary-lig-values> = [ discretionary-ligatures | no-discretionary-ligatures ]
<historical-lig-values>    = [ historical-ligatures | no-historical-ligatures ]
<contextual-alt-values>    = [ contextual | no-contextual ]

各个值具有以下含义:

normal
值为 normal 指定启用常见的默认功能,在下一节中详细描述。 对于 OpenType 字体,常见的连字和上下文形式默认启用,分散性和历史连字未启用。
none
指定明确禁用此属性覆盖的所有类型的连字和上下文形式。在不认为需要连字的情况下,这可能提高文本渲染速度。
common-ligatures
启用显示常见连字(OpenType 功能:liga, clig)。对于 OpenType 字体,常见连字默认启用。
常见连字示例
no-common-ligatures
禁用显示常见连字(OpenType 功能:liga, clig)。
discretionary-ligatures
启用显示分散性连字(OpenType 功能:dlig)。哪种连字是分散性或可选的由字体设计师决定,因此作者需要参考特定字体的文档来了解哪些连字被认为是分散性的。
分散性连字示例
no-discretionary-ligatures
禁用显示分散性连字(OpenType 功能:dlig)。
historical-ligatures
启用显示历史连字(OpenType 功能:hlig)。
历史连字示例
no-historical-ligatures
禁用显示历史连字(OpenType 功能:hlig)。
contextual
启用显示上下文交替(OpenType 功能:calt)。虽然严格来说,这不是连字功能,但像连字一样,此功能通常用于使字形与周围上下文的形状协调一致。对于 OpenType 字体,此功能默认启用。
上下文交替示例
no-contextual
禁用显示上下文交替(OpenType 功能:calt)。

必需的连字(即正确渲染复杂脚本所需的连字)不受上述设置影响,包括 none(OpenType 功能:rlig)。

6.5. 下标和上标形式:font-variant-position 属性

名称: font-variant-position
值: normal | sub | super
初始值: normal
适用对象: 所有元素和文本
继承性:
百分比: 不适用
计算值: 按指定
规范顺序: 按语法
动画类型: 离散
测试

该属性用于启用排版中的下标和上标字形。它们是与默认字形相同的字形,但设计为在同一个em盒内布局,使用与默认字形相同的基线,并且不会调整大小或重新定位基线。它们被明确设计为与周围文本匹配,并且更易读,不会影响行高。

真实下标字形与合成下标字形的比较

上:下标字形;下:典型的合成下标字形

各个值的含义如下:

normal
未启用以下列出的任何功能。
sub
启用下标变体显示(OpenType 功能: subs)。
super
启用上标变体显示(OpenType 功能: sups)。

由于下标和上标的语义性质,如果在一段连续文本中,值为subsuper,但并非所有字符都有变体字形,则应为所有字符合成字形,并使用减少的字形形式。这是在每一段执行,以避免混合使用变体字形和合成字形导致不对齐。

上标变体字形与合成上标字形的比较

左:上标变体字形;中:合成上标字形;右:错误的混合结果

在仅应用于包含上标或下标字形的文本的文本装饰中,可能使用合成字形,以避免装饰放置出现问题。

过去,用户代理曾使用 font-sizevertical-align 来模拟 subsup 元素的下标和上标。为了定义下标和上标的向后兼容方式,建议作者使用条件规则 [CSS3-CONDITIONAL],以便旧的用户代理仍然通过旧机制渲染下标和上标。

由于 font-size: smaller 通常用于这些元素,应用于下标和上标文本的有效缩放因子取决于文本的大小。对于较大的文本,字体大小通常减少三分之一,但对于较小的文本,缩小的幅度可能更小。即使在使用小文本大小的元素中,下标和上标仍然保持可读性。用户代理在决定如何合成下标和上标字形时应考虑到这一点。

OpenType 字体格式在 OS/2 表中定义了下标和上标度量 [OPENTYPE],但实际上这些度量并不总是准确,因此在合成下标和上标字形时不能完全依赖它们。

作者应注意,字体通常只为字体支持的所有字符的子集提供下标和上标字形。例如,尽管下标和上标字形通常可用于拉丁数字,但标点符号和字母字符的字形较少提供。该属性定义的合成回退规则试图确保下标和上标始终显示,但如果使用的字体未为下标或上标中的所有字符提供合适的替代字形,则外观可能不会符合作者预期。

该属性不是累积性的。将其应用于下标或上标内的元素不会嵌套下标或上标字形的放置。在值为 subsuper 的文本运行中包含的图像将按其在 normal 值下的显示方式绘制。

由于这些限制,不建议在用户代理样式表中使用 font-variant-position 属性。作者应在下标或上标仅包含字体支持的字符的狭窄范围时使用该属性。

变体字形使用与默认字形相同的基线。基线位置没有变化,因此使用变体字形不会影响行内框的高度或改变行框的高度。这使得上标和下标变体非常适合在多列布局等需要保持固定行距的情况下使用。

一个典型的用户代理默认样式,用于 sub 元素:

sub {  vertical-align: sub;
  font-size: smaller;
  line-height: normal;
}

使用 font-variant-position 来指定排版下标, 这种方式在旧的用户代理中仍然会显示下标:

@supports ( font-variant-position: sub ) {
  sub {
  vertical-align: baseline;
  font-size: 100%;
  line-height: inherit;
  font-variant-position: sub;
  }

}

支持 font-variant-position 属性的用户代理 将选择下标变体字形并呈现此内容, 不会调整基线或字体大小。 旧的用户代理将忽略 font-variant-position 属性定义, 并使用下标的标准默认设置。

6.6. 大写方式: font-variant-caps 属性

名称: font-variant-caps
值: normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps
初始值: normal
应用于: 所有元素和文本
是否继承:
百分比: 不适用
计算值: 按指定
规范顺序: 按语法
动画类型: 离散
测试

该属性允许选择用于小型或小巧大写字母或标题字母的备用字形。 这些字形经过专门设计,以与周围的常规字形很好地融合, 保持重量和可读性,这在文本只是为了适应此目的而调整大小时会受到影响。

各个值的含义如下:

normal
没有启用下面列出的功能。
small-caps
启用小型大写字母的显示(OpenType 功能:smcp)。 小型大写字母字形通常使用大写字母的形式,但缩小到小写字母的大小。
小型大写字母示例
all-small-caps
启用大小写字母的小型大写字母显示(OpenType 功能:c2sc, smcp)。
petite-caps
启用小型大写字母的显示(OpenType 功能:pcap)。
all-petite-caps
启用大小写字母的小型大写字母显示(OpenType 功能:c2pc, pcap)。
unicase
启用混合了大写字母小型大写字母和常规小写字母的显示(OpenType 功能:unic)。
titling-caps
启用标题大写字母的显示(OpenType 功能:titl)。 大写字母字形通常设计用于与小写字母一起使用。 当在全大写标题序列中使用时,它们可能显得太强。 标题大写字母专为这种情况设计。

这些字形的可用性取决于字体的功能列表中是否定义了某个功能。 用户代理可以选择根据每个脚本来决定这一点, 但明确不应基于每个字符来做出决定。

某些字体可能只支持部分或不支持此属性描述的任何功能。 为了与 CSS 2.1 向后兼容, 如果指定了 small-capsall-small-caps, 但某个字体没有可用的小型大写字母字形, 用户代理应模拟一个小型大写字母字体, 例如通过使用常规字体并用缩小版本的大写字母字形 替换小写字母的字形 (在 all-small-caps 的情况下, 替换大小写字母的字形)。

合成小型大写字母与真实小型大写字母对比

合成小型大写字母与真实小型大写字母对比

font-feature-settings 属性 也会影响是否使用模拟小型大写字母字体的决定 (与 CSS Fonts 3 不同)。

#example1 { font-variant-caps: small-caps; }#example2 { font-variant-caps: small-caps; font-feature-settings: 'smcp' 0; }

对于不支持小型大写字母的字体,#example1 和 #example2 都应以合成的小型大写字母呈现。然而,对于支持小型大写字母的字体,#example1 应以原生的小型大写字母呈现,而 #example2 则不应以任何小型大写字母(无论是原生的还是合成的)呈现。

为了匹配周围的文本,当启用这些功能时,字体可能会为无区分大小写的字符提供备用字形,但当用户代理模拟小型大写字母时,不能尝试为被认为是无区分大小写的代码点模拟替代字形。

无区分大小写字符与小型大写字母、全小型大写字母启用时的效果

无区分大小写字符与小型大写字母、全小型大写字母启用时的效果

如果为不支持这些功能的字体指定了 petite-capsall-petite-caps, 则该属性的行为与分别指定 small-capsall-small-caps 相同。 如果为不支持该功能的字体指定了 unicase, 则该属性的行为就像 small-caps 仅应用于小写化的大写字母一样。 如果为不支持该功能的字体指定了 titling-caps, 则该属性不会产生可见效果。 当使用模拟的小型大写字母字形时, 对于缺乏大写和小写字母的脚本,small-capsall-small-capspetite-capsall-petite-capsunicase 不会产生可见效果。

当使用大小写转换来模拟小型大写字母时, 大小写转换必须与 text-transform 属性所使用的转换相匹配。

作为最后的手段, 可以用常规字体中的未缩放的大写字母字形替换小型大写字母字体中的字形, 使得文本看起来像是全大写字母。

在充满首字母缩略词的文本中使用全小型大写字母以提高可读性

在充满首字母缩略词的文本中使用小型大写字母以提高可读性

带有首行小型大写字母的斜体引用:

blockquote            { font-style: italic; }blockquote:first-line { font-variant: small-caps; }

<blockquote>I’ll be honor-bound to slap them like a haddock.</blockquote>

6.7. 数字格式化: font-variant-numeric 属性

名称: font-variant-numeric
值: normal | [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero ]
初始值: normal
应用于: 所有元素和文本
是否继承:
百分比: 不适用
计算值: 按指定
规范顺序: 按语法
动画类型: 离散
测试

指定对数字格式的控制。下面的示例展示了如何组合其中一些值来影响支持这些功能的字体的表格数据渲染。在正常的段落文本中,使用比例数字,而在表格中使用表格数字,以便数字列正确对齐:

组合数字样式

使用数字样式

可能的组合:

<numeric-figure-values>   = [ lining-nums | oldstyle-nums ]
<numeric-spacing-values>  = [ proportional-nums | tabular-nums ]
<numeric-fraction-values> = [ diagonal-fractions | stacked-fractions ]

各个值的含义如下:

normal
没有启用下面列出的功能。
lining-nums
启用对齐数字的显示(OpenType 功能:lnum)。
oldstyle-nums
启用旧式数字的显示(OpenType 功能:onum)。
proportional-nums
启用比例数字的显示(OpenType 功能:pnum)。
tabular-nums
启用表格数字的显示(OpenType 功能:tnum)。
diagonal-fractions
启用斜线分数的显示(OpenType 功能:frac)。
斜线分数示例
stacked-fractions
启用堆叠分数的显示(OpenType 功能:afrc)。
堆叠分数示例
ordinal
启用用于序数的字母形式(OpenType 功能:ordn)。
序数示例
slashed-zero
启用带斜线的零的显示(OpenType 功能:zero)。
斜线零示例

ordinal 的情况下,虽然序数形式通常与上标形式相同,但它们的标记方式不同。

对于上标,变体属性仅应用于包含上标的子元素:

sup { font-variant-position: super; }
x<sup>2</sup>

对于序数,变体属性应用于整个序数,而不仅仅是后缀(或包含序数的段落):

.ordinal { font-variant-numeric: ordinal; } 
<span class="ordinal">17th</span>

在这种情况下,只有 "th" 会以序数形式显示,数字将保持不变。 根据所用语言的排版传统,序数形式可能与上标形式有所不同。 例如,在意大利语中,序数形式有时会在设计中包含下划线。

一个简单的牛排腌料配方,使用自动分数和旧式数字显示:

.amount { font-variant-numeric: oldstyle-nums diagonal-fractions; } 
<h4>Steak marinade:</h4> 
<ul> 
  <li><span class="amount">2</span> tbsp olive oil</li> 
  <li><span class="amount">1</span> tbsp lemon juice</li>
  <li><span class="amount">1</span> tbsp soy sauce</li> 
  <li><span class="amount">1 1/2</span> tbsp dry minced onion</li> 
  <li><span class="amount">2 1/2</span> tsp italian seasoning</li> 
  <li>Salt &amp; pepper</li> 
</ul> 
 
<p>Mix the meat with the marinade 
and let it sit covered in the refrigerator 
for a few hours or overnight.</p>

请注意,分数功能仅应用于数值,而不是整个段落。 字体通常使用基于斜杠 ('/') 字符的上下文规则实现此功能。 因此,它不适合作为段落级样式使用。

6.8. 变体和饰线: font-variant-alternates 属性

名称: font-variant-alternates
值: normal | [ stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) ]
初始值: normal
应用于: 所有元素和文本
是否继承:
百分比: 不适用
计算值: 按指定
规范顺序: 按语法
动画类型: 离散
测试
<feature-value-name> = <ident>

对于每个字符,字体除了提供默认字形外,还可以提供各种替代字形。 该属性提供了对这些替代字形选择的控制。

对于下面列出的许多属性值,可以提供多个不同的替代字形。 替代字形的数量以及它们的含义是字体特定的,因此在下面的值定义中标记为 字体特定。 由于这些替代字形的性质是字体特定的,@font-feature-values 规则用于为 特定字体系列或字体集定义值,将字体特定的数字 <feature-index> 与自定义 <feature-value-name> 相关联,然后在该属性中使用该值来选择特定的替代字形:

@font-feature-values Noble Script { @swash { swishy: 1; flowing: 2; } }

p { 
  font-family: Noble Script; 
  font-variant-alternates: swash(flowing); /* 使用第2号饰线替代字形 */ 
} 

当某个特定的 <feature-value-name> 未定义时, 计算值必须与定义时相同。但是, 包含这些未定义的 <feature-value-name> 标识符的属性值在选择字形时必须被忽略。

/* 这两条样式规则实际上是相同的 */

p { font-variant-alternates: swash(unknown-value); } /* 未定义值,忽略 */
p { font-variant-alternates: normal; }

这允许为给定字体集定义和使用值,但在发生回退时会忽略它们,因为字体名称会有所不同。 如果某个值超出了给定字体支持的范围,则该值将被忽略。这些值永远不会应用于通用字体系列。

各个值的含义如下:

normal
未启用以下列出的任何功能。
historical-forms
启用显示历史形式(OpenType 功能:hist)。
历史形式示例
stylistic(<feature-value-name>)
启用显示风格替代(字体特定,OpenType 功能:salt <feature-index>)。
风格替代示例
styleset(<feature-value-name>#)
启用通过风格集显示(字体特定,OpenType 功能:ss<feature-index>,OpenType 当前定义了 ss01ss20)。
风格集示例
character-variant(<feature-value-name>#)
启用显示特定字符变体(字体特定,OpenType 功能:cv<feature-index>,OpenType 当前定义了 cv01cv99)。
swash(<feature-value-name>)
启用显示饰线字形(字体特定,OpenType 功能:swsh <feature-index>, cswh <feature-index>)。
饰线示例
ornaments(<feature-value-name>)
启用用装饰物替换默认字形,如果字体中提供(字体特定,OpenType 功能:ornm <feature-index>)。 某些字体可能会为多种字符提供装饰物字形替代;然而,显示任意字符(例如字母数字)为装饰物是一种不良实践,因为它会扭曲数据的语义。 字体设计者被鼓励将所有装饰物(除非它们已明确编码在 Unicode Dingbats 区块中等)编码为圆点符号(U+2022)的替代字形,以便作者使用 ornaments() 选择所需字形。
装饰物示例
annotation(<feature-value-name>)
启用显示替代注释形式(字体特定,OpenType 功能:nalt <feature-index>)。
替代注释形式示例

6.9. 定义字体特定的替代字形: @font-feature-values 规则

上面列出的 font-variant-alternates 的几个可能值被标记为 字体特定; 一种字体不仅可以为该功能定义单个字形,还可以定义 多个 可能的字形变体,并为每个变体关联一个数字索引,供您选择要启用的字形。

这些数字索引因字体而异; 在一种字体上,swsh 1 功能可能会启用大写 Q 的饰线版本,而在另一种字体上,它可能启用 & 的饰线版本。 因此,在 font-feature-settings 中指定索引需要作者准确了解将在哪个元素上使用哪种字体; 如果出现错误(例如由于字体回退选择了不同的字体),他们可能会意外启用完全不同且不想要的功能! 这也意味着作者不能轻松地为使用不同字体的元素启用相似的功能; 他们必须为每个元素单独设置不同的 font-feature-settings 值,以使用正确的数字索引启用所需的功能。

为了解决这个问题,@font-feature-values 规则允许作者为每个字体面分配特定功能索引的易于理解的名称。 使用这些友好名称,作者可以轻松启用类似的功能,而不必关心所使用的字体(前提是他们已为所有字体定义了该名称),并且可以确保不会意外启用不相关的功能(因为没有为这些名称定义的字体将不会执行任何操作)。

使用常见的名称值可以让作者使用单一的样式规则来涵盖一组字体,这些字体的基础选择器对于每种字体都不同。以下示例中,如果找到任意一种字体,将会使用带圈数字字形:

@font-feature-values Otaru Kisa { 
  @annotation { circled: 1; black-boxed: 3; } 
} 
@font-feature-values Taisho Gothic { 
  @annotation { boxed: 1; circled: 4; } 
} 

h3.title { 
  /* circled form defined for both fonts */ 
  font-family: Otaru Kisa, Taisho Gothic;
  font-variant: annotation(circled); 
} 

试图通过 font-feature-values 显式启用“circled”形式将要求作者确定使用哪种字体; 如果他们期望使用“Otaru Kisa”并编写 font-feature-values: nalt 1;,它会在 Otaru Kisa 中启用“circled”字符,但如果系统回退到 Taisho Gothic,则会启用盒装字符,因为 Taisho Gothic 将 nalt 1 与“boxed”字符关联!

6.9.1. 基础语法

@font-feature-values 规则的前言包含一个字体家族名称列表,接着是一个包含多个 feature-value-block 的块, 一种特殊的子级规则。每个 feature-value-block 包含声明,将作者选择的人性化名称(如“flowing”)映射到相关特性的特性索引。

每个 <font-feature-value> 的含义与 font-variant-alternates 属性的相应值相同。

@font-feature-values = @font-feature-values <family-name># { <declaration-rule-list> }

font-feature-value-type = <@stylistic> | <@historical-forms> | <@styleset> | <@character-variant>
  | <@swash> | <@ornaments> | <@annotation> 

@stylistic = @stylistic { <declaration-list> }
@historical-forms = @historical-forms { <declaration-list> }
@styleset = @styleset { <declaration-list> }
@character-variant = @character-variant { <declaration-list> }
@swash = @swash { <declaration-list> }
@ornaments = @ornaments { <declaration-list> }
@annotation = @annotation { <declaration-list> }
测试

@font-feature-values 的前言是一个用逗号分隔的字体家族名称列表,符合 <family-name> 的定义 对于 font-family 属性。这意味着只能使用命名的字体家族; 规则中包含通用字体或系统字体的列表是语法错误。 但是,如果用户代理将通用字体定义为特定的命名字体(如 Helvetica), 则将使用与该字体家族名称相关的设置。 如果 <family-name> 列表中出现语法错误, 整个 @font-feature-values 规则无效,必须忽略。

@font-feature-values 块接受 <declaration-rule-list> 作为其内容; 这些列表项可以是:

或者

多次指定相同的 <font-feature-value-type> 是有效的; 它们的内容将级联在一起。 每个 <feature-value-block> 接受一个声明列表, 即 字体特性值声明, 声明的名称可以是任何 标识符, 值必须是一个或多个非负整数的列表。

<feature-value-block> 接受任何声明名称; 这些名称必须是标识符, 遵循标准的 CSS 语法规则, 并且 区分大小写(所以 foo: 1;FOO: 2 定义了两个不同的特性)。 每个声明的值必须匹配 <integer [0,∞]>+ 语法, 否则声明无效,必须忽略。

注意: 每个特性名称仅在单个 <feature-value-block> 中是唯一的。 在不同的 <feature-value-block> 之间, 或在不同的 @font-feature-values 规则中的相同类型的 <feature-value-block> 中, 名称可以重复而不会冲突。

对于 <family-name> 中的每个名称,在 @font-feature-values 的前言中, 每个 字体特性值声明 定义了一个映射, 一个 (字体家族名称、特性块名称、声明名称)元组 和来自声明值的一个或多个整数的列表。 如果同一个元组在文档中出现多次 (如在单个块中), 则使用最后定义的。

例如,以下定义了相同的一组字体特性值:
/* 默认 */
@font-feature-values foo {
    @swash { pretty: 1; cool: 2; }
}

/* 重复的声明名称 */
@font-feature-values foo {
    @swash { pretty: 0; pretty: 1; cool: 2; }
}

/* 相同类型的多个块 */
@font-feature-values foo {
    @swash { pretty: 1; }
    @swash { cool: 2; }
}

/* 相同字体家族的多个规则 */
@font-feature-values foo {
    @swash { pretty: 1; }
}
@font-feature-values foo {
    @swash { cool: 2; }
} 

字体特性值声明 中的语法错误会使声明无效并被忽略,但不会使其所在的 字体特性值块 无效。 @font-feature-values 块中的未知规则(未使用预定义的关键字)无效并被忽略,但不会使 @font-feature-values 规则无效。

考虑语法错误处理,以下规则等价:
@font-feature-values Bongo {
    @swash { ornate: 1; }
    annotation { boxed: 4; } /* 应为 @annotation! */
    @swash { double-loops: 1; flowing: -1; } /* 负值 */
    @ornaments ; /* 定义不完整 */
    @styleset { double-W: 14; sharp-terminals: 16 1 } /* 缺少 ; */
    redrum  /* 随机编辑错误 */
} 

上面的示例等同于:

@font-feature-values Bongo {
    @swash { ornate: 1; }
    @swash { double-loops: 1; }
    @styleset { double-W: 14; sharp-terminals: 16 1; } 
} 

如果为某个字体家族定义了多个 @font-feature-values 规则, 则这些规则中的定义结果是这些规则定义的值的并集。这样允许为某个字体家族在站点范围内定义一组命名值, 并为每个页面做出特定的添加。

使用站点范围和每个页面的特性值:

site.css:

@font-feature-values Mercury Serif {
    @styleset {
        stacked-g: 3; /* “双层”版本的 g 和 a */
        stacked-a: 4;
    }
}

page.css:

@font-feature-values Mercury Serif {
    @styleset {
       geometric-m: 7; /* m 的替代版本 */
    }
}

body {
    font-family: Mercury Serif, serif;

    /* 启用 stacked g 和替代的 m */
    font-variant-alternates: styleset(stacked-g, geometric-m);
}

6.9.2. 多值特征值定义

大多数 字体特定font-variant-alternates 属性功能值 只接受单个值 (例如 swash()),该值启用特征。

@font-feature-values Jupiter Serif { 
  @swash { 
    swishy: 5;     /* 表示 ss05 = 1 */ 
    swirly: 2;     /* 表示 ss02 = 1 */ 
  } 
} 

The character-variant() 属性值和 @character-variant 描述符允许 两个值, 该值启用特征(从第一个值)并将其设置为指定的(第二个)值。

@font-feature-values MM Greek { 
  @character-variant { alpha-2: 1 2; }   /* 表示 cv01 = 2 */ 
  @character-variant { beta-3: 2 3; }    /* 表示 cv02 = 3 */ 
} 

对于 styleset() 属性值和 @styleset 规则, 多个值表示启用的样式集。值在 1 到 99 之间的值启用 OpenType 功能 ss01ss99。 但 OpenType 标准仅正式定义了 ss01ss20。 对于 OpenType 字体,解析时值大于 99 或等于 0 时不会生成语法错误,但不会启用 OpenType 功能。

@font-feature-values Mars Serif { 
  @styleset { 
  alt-g: 1;        /* 表示 ss01 = 1 */ 
  curly-quotes: 3; /* 表示 ss03 = 1 */ 
  code: 4 5;       /* 表示 ss04 = 1, ss05 = 1 */ 
  }

  @styleset { 
  dumb: 125;        /* >99,忽略 */ 
  }

  @swash { 
  swishy: 3 5;     /* swash 的多个值,语法错误 */ 
  } 
} 

p.codeblock { 
  /* 表示 ss03 = 1, ss04 = 1, ss05 = 1 */ 
  font-variant-alternates: styleset(curly-quotes, code); 
} 

对于 <@character-variant>,值在 1 到 99 之间的单个值表示启用 OpenType 功能 cv01cv99。对于 OpenType 字体,值大于 99 或等于 0 将被忽略,但在解析时不会生成语法错误,也不会启用 OpenType 功能。当列出两个值时,第一个值表示使用的特征,第二个值表示为该特征传递的值。如果为给定名称分配了两个以上的值,则会发生语法错误,并且整个特征值定义将被忽略。

@font-feature-values MM Greek { 
  @character-variant { alpha-2: 1 2; }   /* 表示 cv01 = 2 */ 
  @character-variant { beta-3: 2 3; }    /* 表示 cv02 = 3 */ 
  @character-variant { epsilon: 5 3 6; } /* 多于两个值,语法错误,定义被忽略 */ 
  @character-variant { gamma: 12; }      /* 表示 cv12 = 1 */ 
  @character-variant { zeta:   20 3; }   /* 表示 cv20 = 3 */ 
  @character-variant { zeta-2: 20 2; }   /* 表示 cv20 = 2 */ 
  @character-variant { silly: 105; }     /* >99,忽略 */ 
  @character-variant { dumb: 323 3; }    /* >99,忽略 */ 
} 

#title { 
  /* 使用第三个替代 beta,第一个替代 gamma */ 
  font-variant-alternates: character-variant(beta-3, gamma); 
} 

p { 
  /* zeta-2 跟随 zeta,表示 cv20 = 2  */ 
  font-variant-alternates: character-variant(zeta, zeta-2); 
} 

.special {
  /* zeta 跟随 zeta-2,表示 cv20 = 3  */ 
  font-variant-alternates: character-variant(zeta-2, zeta); 
} 
使用字符变体匹配拜占庭印章上的文字

使用字符变体显示的拜占庭印章文本

在上图中,红色文本使用包含字符变体的字体渲染,这些字符变体模仿了公元8世纪拜占庭印章上的字符形式。下方两行是使用没有变体的字体显示的相同文本。请注意印章中使用的两个 U 和 N 的变体。

@font-feature-values Athena Ruby { 
  @character-variant { 
  leo-B: 2 1; 
  leo-M: 13 3; 
  leo-alt-N: 14 1; 
  leo-N: 14 2; 
  leo-T: 20 1; 
  leo-U: 21 2; 
  leo-alt-U: 21 4; 
  } 
} 

p { 
  font-variant: discretionary-ligatures 
  character-variant(leo-B, leo-M, leo-N, leo-T, leo-U); 
} 

span.alt-N { 
  font-variant-alternates: character-variant(leo-alt-N); 
} 

span.alt-U { 
  font-variant-alternates: character-variant(leo-alt-U); 
} 

<p>ENO....UP͞RSTU<span class="alt-U">U</span>͞<span class="alt-U">U</span>ΚΑΙTỤẠG̣IUPNS</p> 

<p>LEON|ΚΑΙCONSTA|NTI<span class="alt-N">N</span>OS..|STOIBAṢ.|LIṢROM|AIO<span class="alt-N">N</span></p> 

6.10. 东亚文本渲染:font-variant-east-asian 属性

名称: font-variant-east-asian
值: normal | [ <east-asian-variant-values> || <east-asian-width-values> || ruby ]
初始值: normal
适用: 所有元素和文本
继承:
百分比: n/a
计算值: 如指定
规范顺序: 根据语法
动画类型: 离散
测试

允许控制东亚文本中的字形替换和大小调整。

<east-asian-variant-values> = [ jis78 | jis83 | jis90 | jis04 | simplified | traditional ]
<east-asian-width-values>   = [ full-width | proportional-width ]

各个值具有以下含义:

normal
未启用以下列出的任何功能。
jis78
启用 JIS78 字形渲染 (OpenType 功能: jp78)。
JIS78 字形示例
jis83
启用 JIS83 字形渲染 (OpenType 功能: jp83)。
jis90
启用 JIS90 字形渲染 (OpenType 功能: jp90)。
jis04
启用 JIS2004 字形渲染 (OpenType 功能: jp04)。

各种 JIS 变体反映了日本国家标准中定义的不同字形形式。 字体通常包含最近的国家标准定义的字形, 但有时需要使用较旧的变体, 例如为了匹配标牌。

simplified
启用简体字形渲染 (OpenType 功能: smpl)。
traditional
启用繁体字形渲染 (OpenType 功能: trad)。

simplifiedtraditional 值 允许控制字符的字形形式, 这些字符随着时间的推移已经被简化, 但在某些场合仍然使用旧的、传统的形式。 字体设计的具体上下文可能会对字符和字形形式的确切集合有所不同。

繁体字形示例
full-width
启用全角字形渲染 (OpenType 功能: fwid)。
proportional-width
启用比例字形渲染 (OpenType 功能: pwid)。
按比例间隔的日语示例
ruby
启用 ruby 变体字形渲染 (OpenType 功能: ruby)。 由于 ruby 文本通常比正文文本小, 字体设计师可以为 ruby 设计特殊字形, 这些字形比缩小的默认字形更易读。 只有字形选择受到影响, 没有相关的字体缩放或其他影响行布局的更改。

下方红色 ruby 文本 使用默认字形(上方) 和 ruby 变体字形(下方)显示。 注意笔画粗细的细微差别。

ruby 变体示例

6.11. 字体渲染的整体简写:font-variant 属性

名称: font-variant
值: normal | none | [ [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ] || [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ] || [ stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) ] || [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero ] || [ <east-asian-variant-values> || <east-asian-width-values> || ruby ] || [ sub | super ] || [ text | emoji | unicode ] ]
初始值: normal
适用: 所有元素和文本
继承:
百分比: n/a
计算值: 如指定
规范顺序: 根据语法
动画类型: 离散
测试

font-variant 属性是所有 font-variant 子属性的简写:

normal 重置 font-variant 的所有子属性为初始值。 值 nonefont-variant-ligatures 设置为 none,并将所有其他字体功能属性重置为初始值。 与其他简写类似, 使用 font-variant 会将未指定的 font-variant 子属性重置为初始值。

它不会重置 font-language-overridefont-feature-settingsfont-variation-settings 的值。

6.12. 低级字体特性设置控制:font-feature-settings 属性

名称: font-feature-settings
值: normal | <feature-tag-value>#
初始值: normal
适用对象: 所有元素和文本
继承:
百分比: 不适用
计算值: 如指定
规范顺序: 根据语法
动画类型: 离散
测试

此属性提供了对 OpenType 字体特性的低级控制。 它旨在提供一种访问不常用但在特定用例中需要的字体特性的方法。

作者不应使用font-feature-settings来设置下表中的任何字体特性。 相反,请使用高级替代属性,因为:
  1. 高级属性会单独继承。可以设置其中一个而不会影响整个font-feature-settings列表。
  2. 某些高级属性可以为不支持字体特性的字体合成特性。
如果要设置此字体特性 则使用此代替 而非 font-feature-settings 备注
字距调整 (kern) 或垂直字距调整 (vkrn) font-kerning: normal font-kerning 属性将根据writing-mode设置 kernvkrn 特性。
标准连字 (liga) 或上下文连字 (clig) font-variant-ligatures: common-ligatures
任意连字 (dlig) font-variant-ligatures: discretionary-ligatures
历史连字 (hlig) font-variant-ligatures: historical-ligatures
上下文替代 (calt) font-variant-ligatures: contextual
下标 (subs) font-variant-position: sub
上标 (sups) font-variant-position: super
小型大写字母 (smcp) font-variant-caps: small-caps
大写字母的小型大写字母 (c2sc) font-variant-caps: all-small-caps
小型大写字母 (pcap) font-variant-caps: petite-caps
大写字母的小型大写字母 (c2pc) font-variant-caps: all-petite-caps
统一大小写字母 (unic) font-variant-caps: unicase
标题 (titl) font-variant-caps: titling-caps
对齐数字 (lnum) font-variant-numeric: lining-nums
旧式数字 (onum) font-variant-numeric: oldstyle-nums
比例数字 (pnum) font-variant-numeric: proportional-nums
表格数字 (tnum) font-variant-numeric: tabular-nums
分数 (frac) font-variant-numeric: diagonal-fractions
替代分数 (afrc) font-variant-numeric: stacked-fractions
序数 (ordn) font-variant-numeric: ordinal
带斜杠的零 (zero) font-variant-numeric: slashed-zero
历史形式 (hist) font-variant-alternates: historical-forms
风格替代 (salt) font-variant-alternates: stylistic() 通过创建 @font-feature-values 规则来定义要使用的替代。
字符变体 1 - 字符变体 99 (cv01 - cv99) font-variant-alternates: character-variant() 通过创建 @font-feature-values 规则来定义要使用的字符变体。
花体 (swsh) 或上下文花体 (cswh) font-variant-alternates: swash() 通过创建 @font-feature-values 规则来定义要使用的花体。
装饰 (ornm) font-variant-alternates: ornaments() 通过创建 @font-feature-values 规则来定义要使用的装饰。
替代注释形式 (nalt) font-variant-alternates: annotation() 通过创建 @font-feature-values 规则来定义要使用的注释。
JIS78 形式 (jp78) font-variant-east-asian: jis78
JIS83 形式 (jp83) font-variant-east-asian: jis83
JIS90 形式 (jp90) font-variant-east-asian: jis90
JIS2004 形式 (jp04) font-variant-east-asian: jis04
简体形式 (smpl) font-variant-east-asian: simplified
繁体形式 (trad) font-variant-east-asian: traditional
全宽 (fwid) font-variant-east-asian: full-width
比例宽度 (pwid) font-variant-east-asian: proportional-width
注音形式 (ruby) font-variant-east-asian: ruby

例如,没有 font-variant 值可以控制科学下标(用于化学式的小数字)。 使用它们可以增强可读性,因此必须通过 font-feature-settings 启用:

.chem {
  font-feature-settings: 'sinf'
}
科学下标在化学公式中的应用
科学下标提高了化学公式的可读性

整个属性值是一次性设置的。 与 font-variant 属性不同, 不能通过添加或删除个别功能来修改继承的值。

值为 normal 表示此属性不影响字形选择或定位。

功能标签值具有以下语法:

<feature-tag-value> = <opentype-tag> [ <integer [0,]> | on | off ]?
<opentype-tag> = <string>

<opentype-tag> 是区分大小写的 OpenType 功能标签。 如 OpenType 规范中所述 [OPENTYPE], 功能标签包含四个 ASCII 字符。 长度大于或小于四个字符的标签,或包含 U+20–7E 范围以外字符的标签都是无效的。 功能标签只需匹配字体中定义的功能标签, 因此不局限于明确注册的 OpenType 功能。 自定义功能标签的字体应遵循 OpenType 规范中定义的 标签命名规则 [OPENTYPE-FEATURES]

不存在于字体中的功能标签将被忽略; 用户代理不得尝试基于这些功能标签生成回退行为。 唯一的例外是 用户代理可以为包含 kern 表的字体合成性支持 kern 功能 但缺乏在 GPOS 表中支持的 kern 功能。

通常,作者应 使用 font-kerning 属性 来显式启用或禁用字距调整 因为该属性始终影响带有任一类型字距调整数据的字体。

如果存在值,则表示用于字形选择的索引。 <integer> 值必须大于或等于 0。 值为 0 表示功能被禁用。 对于布尔功能, 值 1 启用该功能。 对于非布尔功能, 值为 1 或更大表示启用该功能 并指示功能选择索引。 值 on 相当于 1 而 off 相当于 0。 如果省略了值,则默认值为 1。

font-feature-settings 的计算值是一个映射, 因此指定值中的任何重复项都不得保留。 如果同一功能标签多次出现, 最后一次出现的值将覆盖 该轴之前的所有值。

font-feature-settings 的计算值包含去重的功能标签, 并按代码单元升序排列。

font-feature-settings: "sinf" 1;       /* sinf=1 启用科学下标 */
font-feature-settings: "sinf" on;      /* sinf=1 启用科学下标 */
font-feature-settings: 'sinf';         /* sinf=1 启用科学下标 */
font-feature-settings: "sinf" off;     /* sinf=0 禁用科学下标 */
font-feature-settings: "sinf", 'twid'; /* sinf=1, twid=1 启用科学下标和三分之一宽度 */
font-feature-settings: "sinf" "twid";  /* 无效,需要使用逗号分隔的列表 */
font-feature-settings: "silly" off;    /* 无效,标签过长 */
font-feature-settings: "PKRN";         /* PKRN=1 启用自定义功能 */
font-feature-settings: sinf;           /* 无效,标签必须是字符串 */

当指定的值超出字体支持的范围时,其行为是明确未定义的。 对于布尔型功能,一般情况下这些值将启用该功能。 对于非布尔型功能, 超出范围的值通常相当于 0 值。 然而, 在这两种情况下,具体行为 将取决于字体的设计方式 (特别是用于定义功能的查找类型)。

实现可能会选择忽略关闭 OpenType 规范中规定为必需的功能, 例如必需连字 “rlig”。

测试

虽然功能标签是专门为 OpenType 功能定义的, 但其他支持字体功能的现代字体格式的功能标签 未来可能会添加。 在可能的情况下, 为其他字体格式定义的功能应尽量遵循 已注册的 OpenType 标签模式。

以下日文文本将使用半角片假名字符渲染:

body { font-feature-settings: "hwid"; /* 半角 OpenType 功能 */ }

<p>毎日カレー食べてるのに、飽きない</p>

6.13. 字体语言覆盖:font-language-override 属性

名称: font-language-override
值: normal | <string>
初始值: normal
应用于: 所有元素和文本
是否继承:
百分比: N/A
计算值: 指定字符串或关键字 none
规范顺序: 根据语法
动画类型: 离散
测试

通常,作者可以通过设置元素的内容语言来控制语言特定的字形替换和定位,正如上文所述

<!-- 使用 S’gaw Karen 特定特性显示文本 -->
<p lang="ksw">...</p>

在某些情况下,作者可能需要指定与内容语言不同的语言系统,例如为了模仿另一种语言的排版传统。font-language-override 属性允许作者明确指定字体的语言系统,覆盖由内容语言隐含的语言系统。

值具有以下含义:

normal
指定在使用 OpenType 字体时,元素的内容语言用于推断 OpenType 语言系统
<string>
四个字符的区分大小写 OpenType 语言系统标签,指定要使用的 OpenType 语言系统,而不是由元素语言隐含的语言系统。如果字符串长度少于四个字符,则在末尾用空格 (U+0020) 填充,使长度为 4,然后进行匹配。

未知的 OpenType 语言系统标签将被默默忽略,不会影响字形选择和定位。

7. 字体特性和变化解析

如前一节所述, 字体特性和变化可以通过多种方式启用, 无论是通过使用 font-variantfont-feature-settingsfontfont-variation-settings 在样式规则中 或在 @font-face 规则中。 这些设置的联合解析顺序如下定义。 通过 CSS 属性定义的特性将应用于布局引擎默认特性之上。

7.1. 默认特性

对于 OpenType 字体, 用户代理必须启用 OpenType 文档中 为给定脚本和书写模式定义的默认特性。 必须默认启用必要的连字、常见连字和上下文形式 (OpenType 特性:rlig, liga, clig, calt), 以及本地化形式 (OpenType 特性:locl), 和为正确显示组合字符和符号所需的特性 (OpenType 特性:ccmp, mark, mkmk)。 这些特性必须始终启用, 即使 font-variantfont-feature-settings 属性的值为 normal。 只有在作者显式覆盖时,才会禁用各个特性, 例如当 font-variant-ligatures 设置为 no-common-ligatures 时。

测试

为了处理复杂的脚本,如阿拉伯语蒙古语天城文,需要额外的特性。 对于垂直文本中的直立文本, 必须启用垂直替代(OpenType 特性:vert)。

7.2. 特性和变化的优先级

一般和字体特定的字体特性属性设置按照以下顺序解析,按优先级升序排列。此顺序用于构建影响给定文本段的字体特性组合列表。

  1. 默认启用的字体特性被应用,包括给定脚本所需的特性。参见§ 7.1 默认特性了解相关描述。

  2. 通过 font-weightfont-widthfont-style 属性启用的字体变化被应用。

    由于字体选择的影响,font-style 启用的值将受到影响,因为此属性可能选择斜体或倾斜字体。应用的值是根据字体匹配算法确定的最接近匹配的值。用户代理必须由于 font-style 属性最多应用一个值;不能同时设置 "ital" 和 "slnt" 值。

    如果所选字体是在 @font-face 规则中定义的,则在此步骤中应用的值应限制在 font-weightfont-widthfont-style 描述符的值范围内。

    然后,在此步骤中应用的值应再次限制在字体支持的值范围内。

  3. 应用由 lang/xml:lang 继承值指定的语言。

  4. 如果字体是通过 @font-face 规则定义的,则应用由 font-language-override 描述符隐含的字体语言覆盖。

  5. 如果字体是通过 @font-face 规则定义的,并且该 @font-face 规则包含至少一个有效的 font-named-instance 描述符且其值不是 none,并且加载的字体资源根据 § 5.1 本地化名称匹配 规则包含具有该名称的命名实例,则应用该命名实例表示的所有变化值。这些值将被限制在字体支持的值范围内。

  6. 如果字体是通过 @font-face 规则定义的,则应用由 font-variation-settings 描述符隐含的字体变化。

  7. 如果字体是通过 @font-face 规则定义的,则应用由 font-feature-settings 描述符隐含的字体特性。

  8. 应用由 font-language-override 属性的值隐含的字体语言覆盖。

  9. 应用由 font-optical-sizing 属性的值隐含的字体变化。

  10. 应用由 font-variant 属性隐含的字体特性、相关的 font-variant 子属性和任何其他使用 OpenType 特性的 CSS 属性(例如 font-kerning 属性)。

  11. 应用由 font-variantfont-feature-settings 以外的属性确定的特性设置。例如,设置 letter-spacing 属性的非默认值会禁用可选连字。

  12. 应用由 font-variation-settings 属性隐含的字体变化。这些值应限制在字体支持的值范围内。

  13. 应用由 font-feature-settings 属性隐含的字体特性。

测试

此顺序允许作者为 @font-face 规则内的字体设置一组通用默认值,然后为特定元素通过属性设置进行覆盖。通用属性设置会覆盖 @font-face 规则中的设置,而低级字体特性设置会覆盖 font-variant 属性设置。

对于包含多个相同特性值的字体特性设置组合列表,使用最后一个值。当字体不支持给定的基础字体特性时,文本将以未启用该字体特性的方式进行渲染;字体回退不会发生,也不会尝试合成该特性,除非在特定属性中明确定义。

7.3. 特性优先级示例

使用以下样式,当数字在段落中使用时将以比例形式显示,但在价格表中则显示为表格式:
body {
  font-variant-numeric: proportional-nums;
}

table.prices td {
  font-variant-numeric: tabular-nums;
}
@font-face 规则也可以通过使用 local()src 描述符中访问本地可用字体特性,定义如下 @font-face
@font-face {
  font-family: BodyText;
  src: local("HiraMaruPro-W4");
  font-variant: proportional-width;
  font-feature-settings: "ital"; /* CJK 文本中的拉丁斜体特性 */
}

body { font-family: BodyText, serif; }

如果可用,将使用日语字体 "Hiragino Maru Gothic"。当进行文本渲染时,日语假名将按比例间隔,拉丁文本将显示为斜体。使用回退的衬线字体渲染的文本将使用默认的渲染属性。

在下面的示例中,任选连字仅对可下载的字体启用,但在 class 为 "special" 的 span 中禁用:
@font-face {
  font-family: main;
  src: url(fonts/ffmeta.woff) format("woff");
  font-variant: discretionary-ligatures;
}

body         { font-family: main, Helvetica; }
span.special { font-variant-ligatures: no-discretionary-ligatures; }

假设使用 font-feature-settings 规则启用任选连字:

body         { font-family: main, Helvetica; }
span         { font-feature-settings: "dlig"; }
span.special { font-variant-ligatures: no-discretionary-ligatures; }

在这种情况下,任选连字将会在 class 为 "special" 的 span 中呈现。这是因为 font-feature-settingsfont-variant-ligatures 属性均适用于这些 span。尽管 font-variant-ligaturesno-discretionary-ligatures 设置有效地禁用了 OpenType "dlig" 特性,但由于 font-feature-settings 在之后解析,"dlig" 值重新启用了任选连字。

8. 字体变化属性

注意:本节中使用的技术称为“字体变化”。其中一种字体的实例称为“可变字体”。

8.1. 光学尺寸控制:font-optical-sizing 属性

名称: font-optical-sizing
值: auto | none
初始值: auto
应用于: 所有元素和文本
是否继承:
百分比: 不适用
计算值: 指定的关键字
规范顺序: 按照语法
动画类型: 离散
测试

在排版上,不同大小的文本在视觉上通常会受益于略有不同的表现形式。例如,为了提高小尺寸文本的可读性,笔画通常更粗,衬线更大。大尺寸文本通常具有更精致的形状,笔画的粗细对比更加明显。

auto
用户代理可以根据字体大小和屏幕的像素密度来调整字形的形状。对于使用字体变化的 OpenType 和 TrueType 字体,通常使用“opsz”字体变化来实现此目的。
none
用户代理不得为光学尺寸调整字形的形状。
不同光学尺寸下的文本,标准化为相似的物理尺寸
Century Expanded 在模拟金属形式中的每种尺寸。不同的光学尺寸,标准化为相同的物理尺寸,以保持风格特征并提高可读性。

font-size 必须在为 "opsz" 轴选择变化值时考虑,但也可以考虑其他信号。

注意:用户代理应为 "opsz" 轴提供一个接近 font-size 使用值的值。然而,用户代理可能希望考虑其他因素,例如屏幕的像素密度,或者文本在查看者视网膜中的视角。不过,实验表明,忽略这些其他次要因素,仅使用 font-size 可能是用户代理选择此值的最佳方式。

像素密度以及文本的视觉大小可能会影响为 font-optical-sizing 选择的变化值。当响应用户操作或样式变化时,像素密度或文本的视觉大小发生变化,用户代理不得为此变化选择新值,除非该变化会引发布局变更。用户代理可以自行决定哪些变化会引发布局变更。

注意:某些用户操作,如缩放,可能不被视为布局变更,如果它们不导致文本重新排版。然而,其他用户操作,如为辅助功能目的增加文本大小,可能会被视为布局变更,因为它们会导致文本重新排版。同样,transform 属性通常不被视为引发布局变更,因为变换通常不会导致文本重新排版。每个用户代理可以自行决定每个操作是否导致布局变化。

用户代理不得在字体未直接执行时合成光学尺寸调整。

用户代理不得选择字体未支持的 "opsz" 轴值。可以通过将选择的值限制在字体支持的范围内来实现此目的。

font-optical-sizingfont-size-adjust 相关联。应用光学尺寸调整时,用户代理必须根据调整后的字体大小应用适当的光学尺寸值,前提是遵守上述限制。

8.2. 低级字体变化设置控制:font-variation-settings 属性

名称: font-variation-settings
值: normal | [ <opentype-tag> <number>]#
初始值: normal
应用于: 所有元素和文本
是否继承:
百分比: 不适用
计算值: 关键字 normal 或者是一个列表,每个项目由字符串和数字组成
规范顺序: 根据语法
动画类型: (见文本)
测试

该属性提供对 OpenType 或 TrueType 字体变化的低级控制。其目的是为不常见但在特定使用情况下需要的字体变化提供访问方式。

作者不应使用 font-variation-settings 来设置下表中的任何变化轴。请改用高级替代属性,因为:
  1. 高级属性单独级联。您可以设置一个而不必设置整个 font-variation-settings 列表。
  2. 某些高级属性可以为不支持字体变化的字体合成。
如果您想设置此变化轴 请使用此替代方案而不是 font-variation-settings 备注
权重 (wght) font-weight font-weight 属性将设置 wght 轴(如果存在)。
宽度 (wdth) font-width font-width 属性将设置 wdth 轴(如果存在)。
斜度 (slnt) 或斜体 (ital) font-style font-style 属性将根据其值设置 slntital 轴。
光学尺寸 (opsz) font-optical-sizing font-optical-sizing 属性将设置 opsz 轴(如果存在)。

使用字体变化设置不会影响字体选择,即使使用相同轴的字体属性会对字体选择产生影响。

如果可能,作者通常应使用与字体变化相关的其他属性(例如 font-optical-sizing),并且仅在特殊情况下使用该属性以访问不常见的字体变化。

例如,建议使用 font-weight: 700 而不是 font-variation-settings: "wght" 700。

值为 normal 意味着不会由于此属性发生字形形状、匹配或定位的变化。

<opentype-tag> 是一个区分大小写的 OpenType 或 TrueType 变化轴名称。 正如 OpenType / TrueType 规范中所规定的,轴名称包含四个 ASCII 字符。轴名称字符串长于或短于四个字符,或者包含 U+20–7E 码位范围以外的字符是无效的。 轴名称只需与字体中定义的轴标签匹配,因此不局限于显式注册的 OpenType / TrueType 变化轴。定义自定义轴名称的字体应遵循 OpenType 规范中的名称规则

如果字体不支持给定的轴,则其值设置将被忽略,因此没有效果;用户代理不得基于这些轴标签尝试合成回退行为。同一 CSS font-variation-settings 声明中的其他轴值不会被忽略。

如果字体支持一个变化轴,但其设定的值超出字体的预定义范围,则将被限制为字体支持的最接近值。

允许值为小数或负数。

注意:建议通过使用 font-style 属性来获得倾斜的字形。然而,如果直接使用 slnt 轴,通过 font-variation-settings,请记住其定义的正角度表示逆时针倾斜,与 CSS 的方向相反。

如果同一轴名称出现多次,则最后一次出现的值将取代之前的任何值。这种去重现象可以通过访问该属性的计算值观察到。

计算值包含已去重的轴名称,按代码单位升序排序。

虽然特别针对 OpenType / TrueType 变化轴进行定义,但未来可能会添加支持字体变化的其他现代字体格式的变化轴。如果可能,为其他字体格式定义的变化应尽量遵循注册的变化轴模式。

使用以下机制可以对 font-variation-settings 进行动画处理。如果两个 font-feature-settings 声明是“相似的”,则可以在它们之间进行动画处理。“相似的”声明是指包含相同属性集(顺序无关)的声明。因为连续的重复属性会代替之前的重复属性,所以即使它们具有不同数量的属性,两个声明也可以是“相似的”。如果两个声明是“相似的”,则动画将在声明中的对应值之间逐对发生。否则,动画不可行。在这种情况下,动画的“起始”值将会在动画过程中以未指定的时间点被交换为“目标”值。

9. 彩色字体支持

彩色字体允许字体文件不仅描述字形边缘的轮廓,还可以描述字形内部的颜色。

一个多彩字体的示例
Multicolore,由 Ivan Filipov 设计
一个多彩字体的示例
Magical Unicorn Neue Pro,由 Arthur Reinders Folmer 设计

在某些使用场景中,例如表情符号,字体中的颜色固定是合适的。而在其他场景中,需要通过样式表控制所使用的颜色。

测试

CSS 提供了两种方式来实现这一点。font-palette 属性允许选择字体中包含的多种调色板之一。@font-palette-values 规则允许覆盖调色板中的一个或多个颜色,甚至可以创建完全不同的调色板。

9.1. 控制彩色字体调色板:font-palette 属性

许多彩色字体文件格式允许字形中的颜色参数化。在这些字体中,颜色在描述每个字形的几何形状时通过索引引用。这些索引在当前活动的调色板中通过字体内的查找表解析。然而,许多字体包含多个调色板,每个调色板包含一组由字体设计师选择的互补颜色,以提供令人愉悦的视觉效果。

此外,某些彩色字体文件格式提供了常规的、无色的字形轮廓,以及彩色版本。

名称: font-palette
值: normal | light | dark | <palette-identifier> | <palette-mix()>
初始值: normal
应用于: 所有元素和文本
是否继承:
百分比: 不适用
计算值: 指定的关键字、标识符或 <palette-mix()> 函数。<palette-mix()> 必须简化为单一关键字或标识符,如果结果调色板等效的话。
规范顺序: 根据语法
动画类型: 通过计算值
测试

使用定义如下的 palette-mix() 函数:

<palette-mix()> = palette-mix(<color-interpolation-method> , [ [normal | light | dark | <palette-identifier> | <palette-mix()> ] && <percentage [0,100]>? ]#{2})
normal
如果color-scheme属性设置为非normal的值,用户代理应选择第一个适用于 light 或 dark 的调色板。 否则,用户代理显示带有默认调色板或默认字形着色的彩色字体。

当某些字体格式要求使用前景色时,用户代理应考虑 color 属性的计算值。

COLR 表格中,颜色索引 0xFFFF 应根据 color 属性进行渲染。
对于 COLR/CPAL 字体,font-palette: normal 通常意味着使用字体中索引 0 的调色板进行渲染。
light
某些彩色字体格式包括标记某些调色板适用于浅色(接近白色)背景的元数据。 此关键字将指示用户代理使用字体文件中标记为浅色背景的第一个可用调色板。 如果字体文件格式不支持此元数据,或者字体中没有调色板标记为适合浅色背景,则该值的行为与normal 相同。
dark
某些彩色字体格式包括标记某些调色板适用于深色(接近黑色)背景的元数据。 此关键字将指示用户代理使用字体文件中标记为适合深色背景的第一个可用调色板。 如果字体文件格式不支持此元数据,或者字体中没有调色板标记为适合深色背景,则该值的行为与normal 相同。
<palette-identifier>
此值标识要使用的 CSS 定义调色板。 用户可以使用 @font-palette-values 规则定义调色板。 如果没有适用的 @font-palette-values 规则存在,此值的行为与normal 相同。

<palette-identifier> 被解析为 <dashed-ident>

注意: 这样的 CSS 定义调色板可以引用字体中已有的调色板,修改字体中已有的调色板,或是一个全新的调色板。

<palette-mix()>
此值定义两个调色板值之间的插值位置,通过 <palette-identifier> 或调色板关键字 normallightdark 或另一个 <palette-mix()> 值标识。

字体的字形必须使用通过为每个调色板颜色索引插值而创建的调色板进行渲染,插值在第一个和第二个指定为参数的调色板之间进行,必要时递归解析<palette-mix()> 函数。

对于每个调色板颜色,插值遵循<color-mix()> 函数的规则。

百分比根据CSS Color 5 § 2.1 百分比归一化进行归一化。

测试

注意:名称lightdark描述了颜色调色板可用的背景,而不是调色板本身的颜色。

当黑暗模式生效时,使用黑暗模式调色板
@media (prefers-color-scheme: dark) {  .banner {font-palette: dark;
  } 
} 
在调色板之间进行动画转换。
@font-palette-values --pink { 
  font-family: Nabla; 
  base-palette: 1; 
} 
@font-palette-values --yellow { 
  font-family: Nabla; 
  base-palette: 7; 
} 
@keyframes animate-palette { 
  from { 
    font-palette: --yellow; 
  } 
  to { 
    font-palette: --pink; 
  } 
} 
p { 
  font-family: Nabla; 
  animation: animate-palette 1.4s infinite alternate linear; 
} 
单词Animate在粉色和黄色调色板之间动画
Nabla Color by typearture.com - 在字体中在调色板1和7之间进行动画。
测试

添加更多示例和图片。

9.2. 用户定义的字体颜色调色板:@font-palette-values 规则

@font-palette-values 规则定义了一个颜色调色板,并将其与特定的字体关联起来。 这允许网页作者选择任意的 <color> 用于颜色字体, 而不必局限于字体文件中的预定义调色板。

注意: OpenType 的 CPAL 表仅限于 sRGB 颜色。 在 <color> 中 使用 @font-palette-values 允许任何 CSS 颜色。 一些实现目前使用的 API 仅限于 sRGB,因此可能会将指定的颜色映射为 sRGB。 这是一个暂时的限制,作者不应依赖这种映射至 sRGB 的方式。

此外,此规则与特定字体的关联允许调色板名称在不同的字体中有不同的应用, 当一个元素使用多个字体时(例如字体回退),可以在多个字体中使用相似的颜色。

注意: 网页作者可能希望为单个字体创建多个调色板, 以便为其网页内容创建多种主题。 网页作者还可能希望为多个字体创建匹配的调色板, 以实现不同字体集的一致设计。

@font-palette-values 规则表示用于字体的颜色调色板。 调色板由颜色的有序集合组成。 使用 @font-palette-values 允许网页作者 引用字体内已有的调色板,以及创建由作者定义颜色填充的调色板。 此外,它允许使用网页作者描述的颜色覆盖调色板中的一组颜色。

调色板始终是 完整的,这意味着不可能描述缺少颜色的调色板。如果颜色缺失, 它们将从由 base-palette 描述符指定的字体中的调色板中获取。

数学函数,例如 calc(),以及 var(),还有 env(),在 @font-palette-values 规则中的描述符值中是有效的。 它们在根元素的上下文中进行计算。相对单位也在根元素的上下文中进行计算。

@font-palette-values 规则由 @font-palette-values at-keyword 以及声明块组成。 它具有以下语法:

@font-palette-values <dashed-ident> { 
    <declaration-list> 
} 
测试

@font-palette-values 规则接受本规范中定义的描述符。

修改 Bixa Color 的颜色调色板。
@font-palette-values --Cooler { 
  font-family: Bixa; 
  base-palette: 1; 
  override-colors: 
        1 #7EB7E4; 
} 
覆盖颜色
Bixa Color by Novo Typo。上图使用字体中的颜色;下图将橙色更改为蓝色。
修改 Handover Sans 的颜色调色板
@font-palette-values --Augusta { 
  font-family: Handover Sans; 
  base-palette: 3; 
  override-colors: 
        1 rgb(43, 12, 9), 
        3 var(--highlight); 
} 

这些描述符仅在定义它们的 @font-palette-values 规则的上下文中应用, 并不适用于文档语言元素。 当一个描述符在一个 @font-palette-values 规则中多次出现时, 只有最后一个描述符声明被使用,所有先前的声明将被忽略。

这些调色板将应用于共享相同字体族名称的每个 @font-face。

我想在绿色调色板中使用两种彩色字体。 第一种字体 Bixxxa 已经有可用的调色板, 但对于 Bungeehee,我需要覆盖一种颜色以获得我的绿色调色板。
@font-face { 
  font-family: Bixxxa; 
  src: url('./bixxxa.woff') format('woff'); 
} 

@font-face { 
  font-family: Bungeehee; 
  src: url('./bungeehee.woff') format('woff'); 
} 

@font-palette-values --ToxicGreen { 
  font-family: Bixxxa; 
  base-palette: 3; /* 这是 Bixxxa 的绿色调色板 */ 
} 

@font-palette-values --ToxicGreen { 
  font-family: Bungeehee; 
  base-palette: 7; /* 这是 Bungeehee 的绿色调色板... */ 
  override-colors: 2 lime; /* ...除了这个粉色,我将其覆盖为石灰绿 */ 
} 

h1 { 
  font-family: Bixxxa; 
  font-palette: --ToxicGreen; 
} 

h2 { 
  font-family: Bungeehee; 
  font-palette: --ToxicGreen; 
} 

示例由 Roel Nieskens 提供

注意: 在多个物理字体共享同一个字体族名称的情况下, (例如使用 unicode-range 创建的复合字体), 如果这些字体有不同的调色板,使用 @font-palette-values 指定部分调色板的结果可能不会符合作者的预期。 在这种情况下,最好提供完整的调色板定义。

在上例中,由于两个不同的字体家族已设置为具有兼容的命名调色板, 因此可以继续编写如下内容:
h3 { 
  font-family: Bixxxa, Bungeehee; 
  font-palette: --ToxicGreen;
} 

这将正确应用所需的调色板,即使它们有不同的调色板编号。

一组 @font-palette-values 规则 定义了哪些作者定义的调色板可用于包含这些规则的文档中。

作者定义的字体颜色调色板只能用于引用它的文档中。 在引用它之外的文档中使用作者定义的颜色调色板将构成安全泄漏, 因为一个页面的内容将能够影响其他页面, 这可能成为攻击者利用的攻击向量。

此 at-rule 遵循 CSS 的前向兼容解析规则。 就像声明块中的属性一样, 任何不被用户代理支持的描述符声明都必须被忽略。@font-palette-values 规则要求有 font-family 描述符; 如果缺少此描述符, @font-palette-values 规则无效并且必须被完全忽略。

在用户代理资源有限、 不支持彩色字体、 或者实现了禁用彩色字体功能的情况下,@font-palette-values 规则必须被简单地忽略; 此规范中定义的各个描述符的行为不应被改变。

9.2.1. 字体族:font-family 描述符

名称: font-family
适用范围: @font-palette-values
值: <family-name>#
初始值: 不适用

此描述符定义了该调色板适用的字体族,使用与§ 5 字体匹配算法相同的字体族列表。 此调色板只会应用于具有这些字体族名称的字体。 此描述符的值意味着只允许命名的字体族,包含通用字体的规则将导致语法错误。 如果字体族列表中出现语法错误,该描述符必须被忽略 (仍然会存在于 CSS OM 中,但不会匹配任何字体族)。

9.2.2. 指定基础调色板:base-palette 描述符

名称: base-palette
适用范围: @font-palette-values
值: light | dark | <integer [0,∞]>
初始值: 不适用
light
某些彩色字体格式包含元数据,标记某些调色板适用于浅色(接近白色)的背景。 此关键字标识字体文件中以这种方式标记的第一个可用调色板。 如果字体文件格式没有考虑此元数据,或者字体中没有调色板以这种方式标记, 则此值行为如同指定了 0。
dark
某些彩色字体格式包含元数据,标记某些调色板适用于深色(接近黑色)的背景。 此关键字标识字体文件中以这种方式标记的第一个可用调色板。 如果字体文件格式没有考虑此元数据,或者字体中没有调色板以这种方式标记, 则此值行为如同指定了 0。
<integer>
标识字体中的(从零开始的)数值调色板索引。
修改 Banner Flag 的颜色调色板
@font-palette-values --Festival { 
  font-family: Banner Flag; 
  base-palette: 1; 
  override-colors: 
        0 rgb(123, 64, 27), 
        1 darkblue, 
        2 var(--highlight); 
} 

此描述符指定字体中的调色板,@font-palette-values 规则将其用作初始值。 如果 <override-colors> 键未在 @font-palette-values 规则中出现, 则 @font-palette-values 规则表示字体中 与此描述符值相同索引的调色板。 如果 <override-colors> 键出现在 @font-palette-values 规则中, 则该描述符值中的每个项将覆盖此 @font-palette-values 块中表示的颜色调色板中的单个颜色。

重命名 Handover Sans 的第三个颜色调色板
@font-palette-values --Augusta { 
  font-family: Handover Sans; 
  base-palette: 3; 
} 

如果此描述符不在 @font-palette-values 中存在, 或者如果字体中不存在与 base-palette 值索引相符的调色板, 则其行为如同指定了 0。 如果字体中不包含任何颜色调色板, 则此 @font-palette-values 规则表示的初始颜色调色板中不包括任何颜色。 可以通过在 @font-palette-values 规则中使用 override-color 描述符覆盖调色板中的颜色。

9.2.3. 覆盖调色板中的颜色:override-colors 描述符

名称: override-colors
适用范围: @font-palette-values
值: [ <integer [0,∞]> <color> ]#
初始值: 不适用

此描述符用于覆盖此 @font-palette-values 规则表示的初始颜色调色板中的颜色。

指定的 <color> 必须是 绝对颜色

override-colors 描述符接受 以逗号分隔的调色板索引项和颜色列表。 列表中的每一项代表一个调色板条目和替换它的颜色。

对于此描述符值中的每个键值对,初始调色板中(即使用 base-palette 描述符的调色板)与该键匹配的颜色将被此描述符值中的颜色覆盖。 超出初始调色板索引范围的键将被忽略。

override-colors 描述符中的调色板索引项是一个从零开始的调色板索引项。

整数值是从零索引的。

如果多个不同键值对的键标识相同的颜色索引(无论是通过名称还是整数), 则最后一个键将用于渲染。然而,在序列化时,两个键值对都会存在。

注意: 这意味着在两个不同的元素上使用相同的 font-palette 值时,可能会产生不同的调色板, 因为在这两个元素的上下文中,@font-palette-values 规则中的变量值可能会有不同的应用。

从 CSS 提供的颜色(作为覆盖或新条目)可以使用任何支持的色彩空间。

修改 Blaka Ink 的颜色调色板
@font-palette-values --Festival { 
  font-family: Blaka Ink; 
  base-palette: 0; 
  override-colors:
    0 oklch(0.63 0.12 105.7), 
    1 color(display-p3 0.23 0.22 0.04), 
    2 color(prophoto-rgb 0.37 0.27 0.09); 
} 

注意: 版本 0 和 1 的 CPAL 表中指定的颜色为 sRGB。

9.3. 选择文本呈现样式:font-variant-emoji 属性

名称: font-variant-emoji
值: normal | text | emoji | unicode
初始值: normal
适用对象: 所有元素和文本
是否继承:
百分比: 不适用
计算值: 指定的关键字
规范顺序: 按语法顺序
动画类型: 离散
测试

此属性允许网页作者选择是否为某些 emoji 代码点使用 emoji 呈现样式或文本呈现样式。 传统上,这些呈现样式是通过将变体选择符 15(U+FE0E)或变体选择符 16(U+FE0F)附加到某些代码点上来选择的。 然而,font-variant-emoji 允许网页作者设置默认的呈现样式, 这可以替代变体选择符。

此属性仅影响 Unicode 列出的 emoji 呈现序列 中的代码点。 在此 CSS 规范中,这些字符被称为 参与 emoji 呈现的代码点。 此属性对其他字符无效。

预计此属性会影响字体回退; 但 font-variant-emoji 与字体回退的具体交互方式尚未明确规定。 然而,变体选择符必须包含在前一个簇中,如上面的 簇匹配 部分所定义。 这一行为的自然结果是,变体选择符不能在与前一个字符不同的字体中呈现。 因此,它会导致字体回退的行为 就像是这些附加的变体选择符是预期的一样; 然后执行字体回退,包括簇回退规则,必须考虑这些"附加"变体选择符的呈现偏好。

即使使用了 font-variant-emoji, 如果元素内容中存在变体选择符 15(U+FE0E)或变体选择符 16(U+FE0F), 它们会覆盖 font-variant-emoji 中指定的渲染方式。 因此,font-variant-emoji 设置的是默认呈现样式, 但文本可以选择不使用该样式。

注意: 不同平台在处理 emoji 呈现序列方面有不同的约定。 跨平台的用户代理可能希望遵循每个平台的惯例, 也可能希望在所有平台上使用相同的方式。 当需要请求 emoji 样式渲染时, 用户代理可能希望忽略不包含彩色表的字体。 另一种用户代理可能希望使用相同的机械簇回退算法, 就像它对任何任意簇使用的那样。

除 FE0E 变体选择符-15 和 U+FE0F 变体选择符-16 之外的其他变体选择符, 不得对字体选择产生任何影响。 如果出现这些变体选择符之一,但所选字体不支持, 则忽略该变体选择符。

BCP47 的 -u- 扩展适用于 langxml:lang,不应在用户代理决定是使用 emoji 呈现还是文本呈现某个特定字符时考虑。

normal
用户代理可以选择以 emoji 样式或文本样式绘制参与呈现的代码点。 用户代理通常在做出此决定时遵循平台惯例。
text
代码点被呈现得如同 U+FE0E 变体选择符-15 已附加到每个 参与呈现的代码点
emoji
代码点被呈现得如同 U+FE0F 变体选择符-16 已附加到每个 参与呈现的代码点
unicode
代码点根据 [UTS51] 作为 emoji 默认、文本默认或仅文本呈现, 具体取决于每个 参与呈现的代码点 的 Emoji 和 Emoji_Presentation 属性值。 如果存在,则 FE0E 变体选择符-15 和 U+FE0F 变体选择符-16 将覆盖单个 参与呈现的代码点 的默认呈现。
要显示 U+1F6CB COUCH AND LAMP 的 emoji 形式, 让 CustomEmoji.ttf 遵循用户代理对该字符 emoji 形式支持的概念, 并使用以下代码:
@font-face { 
  font-family: "Custom Emoji"; 
  src: url("CustomEmoji.ttf") format("truetype"); 
} 
...
<div style="font-family: 'Custom Emoji'; font-variant-emoji: emoji;">&#x1F6CB;</div>

10. 字体分类

一个给定的字体可能属于以下一个或多个类别:

10.1. 已安装字体

字体可以全局安装在设备上。这类字体通常在任何应用程序中都可以访问,即使是没有 CSS 概念的应用程序。支持字体对象的文件存在于用户的设备上,而不是作为远程资源。

已安装字体不能是 Web 字体,Web 字体也不能是已安装字体。

10.2. Web 字体

字体可能由远程资源支持,必须使用用户代理的资源获取机制进行请求。Web 字体由以下两种机制之一表示:

Web 字体不能在与 @font-face 规则关联的文档或拥有 FontFaceSet 的文档之外的任何其他文档中访问。 设备上的其他应用程序不能访问 Web 字体。

已安装字体不能是 Web 字体,Web 字体也不能是已安装字体。

Web 字体会遮盖已安装字体,因此如果已安装字体的系列名称与 Web 字体相同,则无法访问已安装字体。

10.3. 预安装字体和用户安装字体

用户可以选择在其设备上安装字体。 用户安装字体是通过用户的明确操作安装的,例如点击"安装"按钮或将文件复制到设备的特定目录中。 这些字体是用户安装字体,也是已安装字体。 Web 内容作者不应依赖用户安装字体,因为无法保证任何用户都会执行安装特定字体的操作。

请参阅 字体匹配算法,了解用户安装字体如何与字体匹配算法交互。

任何非用户安装的已安装字体都是预安装字体。很可能特定操作系统版本的所有用户都安装了相同的预安装字体集。因此,针对这些操作系统的 Web 内容作者可能希望在 font-family 属性中使用这些字体系列名称。

10.4. 系统字体

系统字体是 system-ui 通用字体系列名称使用的字体。它是预安装字体的一个例子。

测试

11. 字体技术与格式

11.1. 字体技术

features-opentypefeatures-aatfeatures-graphite 技术 是指对字体特性的支持, 通常在 [OPENTYPE] 中通过 GSUBGPOS 表实现, 以及在 [AAT-FEATURES] 中通过 morxkerx 表实现, 并且在 [GRAPHITE] 中 使用 SilfGlatGlocFeatSill 表, 如 Graphite 表格式 中所述。 § 6 字体特性属性 部分描述了与这些功能交互的属性。

variations 技术是指对字体变化的支持, 通常在 [OPENTYPE] 中通过 avarcvarfvargvarHVARMVARSTATVVAR 表实现, 以及在 [AAT-FEATURES] 中通过 avarcvarfvargvar 表实现。 § 2 基本字体属性 部分和 § 8 字体变化属性 部分描述了与这些功能交互的属性。

color-colrv0color-colrv1color-svgcolor-sbixcolor-cbdt 技术是指各种颜色字体文件技术。 每个技术表示一个表 (COLRSVGsbixCBDT) 位于 [OPENTYPE][AAT-FEATURES] 字体中,必须支持这些表以满足此要求。

palettes 技术是指对字体调色板的支持, 通常在 [OPENTYPE][AAT-FEATURES] 中通过 CPAL 表实现。 § 9 颜色字体支持 部分描述了与这些功能交互的属性。

incremental-patchincremental-rangeincremental-auto 技术 是指客户端对增量字体传输的支持 [IFT], 使用 patch-subset、range-request 或 自动协商 这两种方法之一。

有关这些的背景信息,请参阅 [PFE-report]

网页作者可以在 tech 函数中指定 使用 @font-facesrc 描述符 来指示需要支持以正确渲染字体。 这种机制可以用于在请求的支持不存在时优雅地回退到辅助字体。

这个 @font-face 块展示了如何在用户代理上存在支持时使用颜色字体, 如果没有支持,则回退到非颜色字体。
@font-face { 
  font-family: "Trickster"; 
  src: url("trickster-COLRv1.otf") format(opentype) tech(color-COLRv1), 
  url("trickster-outline.otf") format(opentype); 
} 

11.2. 字体格式

本规范定义的格式字符串如下。 <font-format> 值是以下格式的同义词。

字符串 字体格式 常见扩展名 常见媒体类型
"collection" OpenType 集合 .otc, .ttc font/collection
"embedded-opentype" 嵌入式 OpenType .eot application/vnd.ms-fontobject
"opentype" OpenType .ttf, .otf font/otf, font/ttf
"svg" SVG 字体 (已弃用) .svg, .svgz image/svg+xml
"truetype" TrueType .ttf font/ttf
"woff" WOFF 1.0 (Web Open Font Format) .woff font/woff
"woff2" WOFF 2.0 (Web Open Font Format) .woff2 font/woff2
测试

鉴于 TrueType 和 OpenType 在常见使用中的重叠, 格式提示 "truetype" 和 "opentype" 必须被视为同义词; "opentype" 的格式提示并不意味着 该字体包含 Postscript CFF 样式的字形数据 或包含 OpenType 布局信息 (有关此的更多背景信息,请参见 附录 A)。

12. 对象模型

@font-face@font-feature-values 规则的内容可以通过以下对 CSS 对象模型的扩展进行访问。

测试

12.1. CSSFontFaceRule 接口

CSSFontFaceRule 接口表示 <@font-face> 规则。

[Exposed=Window] 
            interface CSSFontFaceRule : CSSRule { 
              readonly attribute CSSStyleDeclaration style; 
            }; 
            

12.2. CSSFontFeatureValuesRule 接口

CSSRule 接口扩展如下:

partial interface CSSRule {  const unsigned short FONT_FEATURE_VALUES_RULE = 14; 
            }; 
            

CSSFontFeatureValuesRule 接口表示 @font-feature-values 规则。

12.3. CSSFontPaletteValuesRule 接口

[Exposed=Window] 
            interface CSSFontPaletteValuesRule : CSSRule { 
              readonly attribute CSSOMString name; 
              readonly attribute CSSOMString fontFamily; 
              readonly attribute CSSOMString basePalette; 
              readonly attribute CSSOMString overrideColors; 
            }; 
            

fontFamilybasePalette 接口根据相应的 CSS 属性语法进行解析。

13. 序列化

13.1. 序列化与字体相关的属性

除非个别属性特别注明,本模块定义的属性遵循 CSSOM § 6.7.2 CSS 值的序列化 的原则。

测试

13.2. 序列化与字体相关的 at-rules

除非个别描述符特别注明,本模块中 at-rules 的描述符遵循 CSSOM § 6.7.2 CSS 值的序列化 的原则。

特别是,遵循简洁表示原则:对于接受一系列值的描述符,如果起始值和结束值相同(范围为零),则该描述符序列化为单个值,而不是范围。

测试
例如,规则:
@font-face { 
  font-family: "foo"; 
  font-weight: 200 200; 
} 

将会序列化为:

@font-face { 
  font-family: "foo"; 
  font-weight: 200; 
} 

此外,遵循仅保留最后定义的值的原则,以及简洁表示的原则,重复指定的元组和多个块将被序列化为仅包含最后定义值的单个块。

例如,声明:
/* 重复的声明名称,以及相同类型的多个块 */ 
@font-feature-values foo { 
  @swash { pretty: 0; cool: 2; } 
  @swash { pretty: 1; } 
} 

将会序列化为:

/* 规范序列化 */ 
@font-feature-values foo {
    @swash { cool: 2; pretty: 1; } 
}

附录A:将平台字体属性映射到 CSS 属性

本附录作为其他章节中描述的一些问题和情况的背景信息,仅供参考。

CSS 中的字体属性设计为独立于底层使用的字体格式;它们可以用于指定位图字体、Type1 字体、SVG 字体,以及常见的 TrueType 和 OpenType 字体。但 TrueType 和 OpenType 格式的某些方面经常会使作者感到困惑,并给不同平台上的实现者带来挑战。

TrueType [TRUETYPE] 最早由 Apple 开发,设计为用于屏幕和打印的轮廓字体格式。微软与 Apple 一起开发了 TrueType 格式,两个平台自此支持 TrueType 字体。TrueType 格式中的字体数据由一组表组成,每个表都有常见的四字母标签名称,包含特定类型的数据。例如,命名信息(包括版权和许可信息)存储在 name 表中。字符映射表 (cmap) 包含字符编码到字形的映射。Apple 后来添加了额外的表,用于支持增强的排版功能,这些字体现在称为 Apple Advanced Typography,或 AAT 字体。微软和 Adobe 开发了一套独立的表用于高级排版,并将其格式称为 OpenType [OPENTYPE]。OpenType 规范在 ISO 中标准化为 Open 字体格式 [OPEN-FONT-FORMAT]

在许多情况下,Microsoft Windows 或 Linux 使用的字体数据与 Apple 的 Mac OS X 使用的字体数据略有不同,因为 TrueType 格式允许跨平台进行显式变化。这包括字体度量、名称和 字符映射 数据。

具体而言,字体族名称数据在不同平台上处理方式不同。对于 TrueType 和 OpenType 字体,这些名称包含在 name 表中的名称记录中,名称 ID 为 1。可以为不同语言环境存储多个名称,但微软建议字体始终至少包含一个美国英语版本的名称。在 Windows 上,微软出于向后兼容性的考虑,决定将此字体族名称限制为最多四个字体;对于更大的分组,可以使用 "首选族"(名称 ID 16)或 "WWS 族"(名称 ID 21)。像 OSX 这样的其他平台没有这个限制,因此字体族名称用于定义所有可能的分组。

其他名称表数据提供用于唯一标识字体家族中特定字样的名称。字体的全名(名称 ID 4)和 Postscript 名称(名称 ID 6)唯一描述单个字样。例如,Gill Sans 字体族的粗体字样的全名为 "Gill Sans Bold",Postscript 名称为 "GillSans-Bold"。对于给定的字样,可以有多个本地化版本的全名,但 Postscript 名称始终是一个由有限的 ASCII 字符组成的唯一名称。

在不同平台上,使用不同的名称来查找字体。例如,在 Windows GDI 的 CreateIndirectFont API 中,可以使用字体族或全名查找某个字样,而在 Mac OS X 上,则使用 CTFontCreateWithName API 调用来查找给定字样,使用的是全名和 Postscript 名称。在 Linux 下,fontconfig API 允许使用这些名称中的任意一个来搜索字体。在平台 API 自动替换其他字体选择的情况下,可能需要验证返回的字体与给定名称匹配。

字体字样的字重可以通过 OS/2 表的 usWeightClass 字段确定,也可以从样式名称(名称 ID 2)推断。同样,字宽可以通过 OS/2 表的 usWidthClass 字段确定,或从样式名称中推断。由于与 Windows GDI API 在权重为 200 或更低时的合成加粗相关的历史原因,字体设计师有时会偏离 OS/2 表中的值,以避免这些权重。

渲染使用上下文形状的复杂脚本(如泰语、阿拉伯语和梵文)需要仅存在于 OpenType 或 AAT 字体中的功能。目前,在 Windows 和 Linux 上使用 OpenType 字体功能支持复杂脚本渲染,而在 Mac OS X 上则同时使用 OpenType 和 AAT 字体功能。

14. 安全性考虑

请参阅下方自我评审问卷中的 91617 项目。

15. 隐私性考虑

根据自我评审问卷:安全与隐私,并结合 第 10 节 字体分类

15.1. 该功能可能会向网站或其他方暴露哪些信息,以及该暴露的目的是什么?

该规范允许使用 Web 字体,这些字体按需请求,但未安装。如果文档或样式表与 Web 字体的来源不同,此网络请求会暴露 Referer 头中的信息,这些信息可能会被字体提供者获取。

除了 Web 字体之外,该规范还继续允许使用自 CSS1 引入的安装字体(包括预安装字体和用户安装字体)。

虽然 Web 字体具有跨平台一致性的优势,但安装字体具有零下载时间的优势。

在某些情况下,尤其是对于支持较差或少数语言,安装字体允许显示信息,这在没有自由许可的 Web 字体支持该语言的情况下无法显示,或者由于延迟或下载时间过长,使用变得不可行,尤其是对于字符库较大的语言,或在较慢或计量连接上。

注意:字体匹配算法中可用的安装字体集合明确未定义。可用的字体集合 已被追踪者用来对用户进行指纹识别,进而降低他们的隐私性。然而,一些安装字体,甚至是用户安装字体,是为了使语言可读而必须的。用户代理可以选择为了语言支持和设计完整性原因使所有安装字体可用,或者为了隐私原因使部分字体不可用。此外,用户代理可能具有额外的功能来微调这种平衡,例如提供接口提示用户明确选择是否使某些请求的字体可用或不可用(可能是按站点设置)。即使在相同操作系统上运行的不同用户代理,也可能在此处平衡不同。

对于执行本地资源渲染的用户代理(例如 HTML 和 CSS 转换为 PDF 的渲染器,或基于 Web 的文字处理器),访问所有安装字体(包括预安装字体和用户安装字体)是提供预期功能的必要条件。

攻击者可以通过查询安装字体获取指纹信息。与旧技术(尤其是 Adobe Flash,它提供了安装字体的完整列表并将此信息发送到 HTTP 头中)相比,此类探测必须逐一进行字体检查,提供字体族名称,然后检查(通过脚本,或使用 unicode-range 有选择地下载 Web 字体,具体取决于用户是否具有支持某个字符的某个字体),字体是否加载。这需要时间,检查几百个以上的字体会引入页面渲染中的明显延迟。

对于特别隐私敏感的环境,选项包括永不下载任何 Web 字体(这会有一些字符可能被错误渲染,甚至无法渲染的风险),或者总是下载所有 Web 字体,无论是否需要(忽略 unicode-range,且可能每次查看页面时都会下载大量未使用的字体)。

15.2. 该规范是否只暴露了实现该功能所需的最少信息?

目前的共识是用户代理必须暴露预安装字体以确保功能的正常运行,但对于是否暴露用户安装字体尚无定论。该规范允许用户代理在字体匹配算法中忽略用户安装字体。一些现有的用户代理已经这样做了。

根据用户类型,最少暴露的信息量有所不同,这目前正在讨论中。这里有一个用户安装字体用户分类,该分类已经被略微扩展

暴露更多信息可能会带来更多指纹识别的风险;而减少信息暴露则降低了指纹识别风险,但同时也减少了功能性,某些情况下可能会对少数语言用户的网络体验造成严重影响。

目前正在讨论是否可能实现一种用户配置选项,允许用户选择是否暴露部分或全部用户安装字体,或者按来源选择性暴露。

此外,也在讨论一种隐私预算的可能性,即惩罚或禁用恶意网页对大量字体的测试,但允许对少量字体测试的无害网页继续运行。

一些用户代理在其隐私浏览、无痕模式或抵制指纹识别模式下,会暴露比正常模式更少的预安装字体集合。

15.3. 该规范如何处理个人信息或可识别个人身份的信息或由此衍生的信息?

该规范不暴露个人信息。

某些情况下,可能会暴露可识别个人身份的信息。例如,对于日本的用户,列举条件启用的日文字体可能不会构成重要的指纹识别向量,但对于在欧洲有日文输入法的用户而言,则可能构成。

15.4. 该规范如何处理敏感信息?

在某些情况下,通过安装字体进行指纹识别可能会暴露敏感信息。例如,受迫害的少数群体可能会通过暴露他们使用的特定语言字体而泄露敏感信息;这可能是通过向第三方服务请求 Web 字体或暴露与该语言相关的预安装字体或用户安装字体实现的。

15.5. 该规范是否引入了跨浏览会话持续存在的来源新状态?

没有。

具体来说,Web 字体必须无法被关联 @font-face 规则的文档之外的任何其他文档访问。同样,字体调色板值仅能供引用它们的文档使用,否则可能会导致安全泄露。

15.6. 该规范向来源暴露了哪些来自底层平台的信息,如配置数据?

system-ui关键字暴露了操作系统的默认系统 UI 字体,这可能会被指纹识别机制利用。

15.7. 该规范是否允许来源访问用户设备上的传感器?

没有。

15.8. 该规范暴露了哪些数据给来源?请说明哪些数据与其他功能暴露的数据相同,无论是在相同还是不同的上下文中。

对于通过样式表加载的第三方 Web 字体,样式表来源可能会通过 Referer 头暴露给第三方。此外,仔细配对 unicode-range 和不同的 src URL,允许第三方看到页面上使用了哪些字符,这对大字符库语言(如 CJK)构成了隐私风险。

对于预加载到 HTML 的第三方 Web 字体,文档来源也可能会被类似地暴露。

15.9. 该规范是否启用了新的脚本执行/加载机制?

没有。

具体来说,对于包含在 OpenType 彩色字体中的 SVG,用于字形定义的 SVG 不应包含 script 元素,且任何出现的 script 元素都不会执行。

15.10. 该规范是否允许来源访问其他设备?

没有。

15.11. 该规范是否允许来源在一定程度上控制用户代理的原生 UI?

攻击者可能会通过确定操作系统并使用与该操作系统相符的本地字体来伪装原生 UI 功能。

15.12. 该规范可能会创建或暴露哪些临时标识符给网络?

无。

15.13. 该规范如何区分第一方和第三方上下文中的行为?

对于字体加载,用户代理必须使用 @font-face 规则内定义的 URL,遵循[HTML]规范定义的 CORS 可用的抓取方法。

15.14. 该规范在用户代理的隐私浏览或“无痕模式”下如何工作?

该规范未做区分。

一些用户代理在这些模式下可能会暴露更少的安装字体。

15.15. 该规范是否包含“安全性考虑”和“隐私性考虑”部分?

是的。

15.16. 该规范是否允许降低默认的安全特性?

没有。

15.17. 该问卷还应当询问什么问题?

它应该询问是否存在恶意负载可能导致应用崩溃,甚至整个操作系统崩溃,或者导致远程代码执行的可能性。

某些情况下,这种可能性确实存在,尤其是针对某些平台,当安装和渲染精心构造的字体时,这一漏洞已被实际利用。

在实际中,运行于具有此类漏洞操作系统上的用户代理会使用字体消毒器检测这些恶意字体并阻止其被使用。

16. 无障碍考虑

使用字体来提供文本的视觉渲染通常不会影响无障碍性。例如,使用屏幕阅读器将文本转换为语音的人不会下载字体,因此不会受到这些字体内容的影响。

然而,这假设字体字形传达的语义与字符传达的语义是一致的。

历史上,这种情况并不总是如此。例如,在早期的 Web 中,常常使用字体(例如“Symbol”字体,尽管其他字体也被使用)使拉丁字母具有希腊字形;虽然这种做法在视觉上有效,但它对屏幕阅读器不起作用,且由于这种映射是特定于字体的,文本也难以搜索或索引。随着 Unicode 的兴起,现在的标准做法是使用希腊字符表示希腊文本,并将字体中的希腊字形映射到希腊字符。

遗憾的是,这种做法仍然存在于设计不良的图标字体中。例如,这种字体可能将“打印机”图标放在拉丁字母“P”上。这种做法会在文本中散布无意义的字母,影响文本搜索和索引,并且如果图标字体未加载,渲染将难以理解,还会妨碍屏幕阅读器的使用。设计良好的字体应将此类图标分配给具有语义意义的字符。例如,可以将打印机图标分配给字符串“printer”或 Unicode 字符 🖨 U+1F5A8(PRINTER)。

17. 致谢

CSS 工作组感谢以下人员:

Peter Constable 对多语言问题的修正。

Nick Sherman 准备了光学尺寸示例图像。

Richard Ishida 准备了乌尔都语样本。

Munira Tursunova 和 Dominik Röttsches 开发了动画字体调色板功能。

John Hudson 详细解释了 OpenType 语言标签的细微差别,并提供了用于显示拜占庭印章文本的字符变体示例。

Elika Etemad 提供了“@font-feature-values”规则的一些初始设计理念。

特别感谢 Tab Atkins Jr. 提供了字体渲染控制部分的文本,以及font-display描述符部分的文本。特别感谢 Ilya Grigorik 和 David Kuettel 帮助开发了这些部分。

18. 变更

18.1. 2021年12月21日工作草案的变更

18.2. 2021年7月29日工作草案的变更

18.3. 2020年11月17日工作草案的变更

18.4. 2019年11月13日工作草案的变更

18.5. 2018年9月20日工作草案的变更

18.6. 2018年4月10日工作草案的变更

18.7. CSS Fonts 3 推荐规范与2018年9月20日的变更

本节总结了 CSS Fonts 4 与 CSS Fonts 3 的变更。

一致性

文档惯例

一致性要求通过描述性断言和 RFC 2119 术语的组合表达。关键字 “MUST(必须)”、 “MUST NOT(不得)”、 “REQUIRED(必需)”、 “SHALL(应当)”、 “SHALL NOT(不应当)”、 “SHOULD(应该)”、 “SHOULD NOT(不应该)”、 “RECOMMENDED(建议)”、 “MAY(可以)” 和 “OPTIONAL(可选)” 在本规范的规范部分中应按照 RFC 2119 中所述解释。然而,为了可读性,这些词语在本规范中并未全部使用大写字母。

本规范中的所有文本都是规范性的,除非明确标记为非规范性部分、示例或注释。[RFC2119]

本规范中的示例以“例如”开头,或者通过 class="example" 这样的方式与规范文本区分开,如下所示:

这是一个说明性示例。

说明性注释以“注释”一词开头,并通过 class="note" 与规范文本区分开,如下所示:

注释,这是一个说明性注释。

规范性建议是为了引起特别注意的规范性部分,并通过 <strong class="advisement"> 与其他规范文本区分开,如下所示:用户代理(UAs)必须提供可访问的替代方案。

测试

与本规范内容相关的测试可能会记录在像这样的“测试”块中。任何此类块都是非规范性的。


一致性类别

本规范的一致性定义了三种一致性类别:

样式表
CSS 样式表
渲染器
解释样式表语义并渲染使用它们的文档的 UA
创作工具
编写样式表的 UA

样式表符合本规范的要求,如果其使用本模块定义的语法的所有语句根据通用 CSS 语法和本模块定义的每个功能的单独语法都是有效的。

渲染器符合本规范的要求,如果它除了按适当的规范定义解释样式表外,还正确解析本规范定义的所有功能,并相应地渲染文档。然而,由于设备限制,UA 无法正确渲染文档并不使其不符合规范。(例如,UA 不需要在单色显示器上渲染颜色。)

创作工具符合本规范的要求,如果它编写的样式表根据通用 CSS 语法和本模块中每个功能的单独语法是语法正确的,并且满足本模块中描述的样式表的所有其他一致性要求。

部分实现

为了使作者能够利用向前兼容的解析规则来分配回退值,CSS 渲染器必须将任何它们没有可用支持级别的 at-rules、属性、属性值、关键字和其他语法结构视为无效(并适当地忽略)。特别是,用户代理不得选择性地忽略不支持的组件值并在单个多值属性声明中接受支持的值:如果任何值被视为无效(因为不支持的值必须是无效的),CSS 要求整个声明被忽略。

不稳定和专有功能的实现

为了避免与未来稳定的 CSS 功能发生冲突,CSS 工作组建议遵循最佳实践来实现不稳定的功能和专有扩展

非实验性实现

一旦规范达到候选推荐阶段,非实验性实现就有可能进行,实现者应发布任何 CR 级别功能的非前缀实现,只要他们能够证明根据规范正确实现了这些功能。

为了建立和维护跨实现的 CSS 互操作性,CSS 工作组要求非实验性 CSS 渲染器在发布任何 CSS 功能的非前缀实现之前,向 W3C 提交实现报告(如果有必要,还需提交用于该实现报告的测试用例)。提交给 W3C 的测试用例将由 CSS 工作组进行审查和修正。

有关提交测试用例和实现报告的更多信息,请访问 CSS 工作组网站:https://www.w3.org/Style/CSS/Test/。如有疑问,请联系public-css-testsuite@w3.org邮件列表。

索引

本规范定义的术语

引用中定义的术语

参考文献

规范性参考文献

[AAT-FEATURES]
Apple Advanced Typography 字体特性注册表。URL: https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS 层叠与继承 5 级。2022年1月13日。CR。URL: https://www.w3.org/TR/css-cascade-5/
[CSS-COLOR-4]
Tab Atkins Jr.; Chris Lilley; Lea Verou. CSS 颜色模块 4 级。2022年11月1日。CR。URL: https://www.w3.org/TR/css-color-4/
[CSS-COLOR-5]
Chris Lilley 等人。CSS 颜色模块 5 级。2022年6月28日。WD。URL: https://www.w3.org/TR/css-color-5/
[CSS-COLOR-ADJUST-1]
Elika Etemad 等人。CSS 颜色调整模块 1 级。2022年6月14日。CR。URL: https://www.w3.org/TR/css-color-adjust-1/
[CSS-ENV-1]
CSS 环境变量模块 1 级。编辑草案。URL: https://drafts.csswg.org/css-env-1/
[CSS-FONTS-4]
John Daggett; Myles Maxfield; Chris Lilley. CSS 字体模块 4 级。2021年12月21日。WD。URL: https://www.w3.org/TR/css-fonts-4/
[CSS-INLINE-3]
Dave Cramer; Elika Etemad. CSS 行内布局模块 3 级。2023年4月1日。WD。URL: https://www.w3.org/TR/css-inline-3/
[CSS-SYNTAX-3]
Tab Atkins Jr.; Simon Sapin. CSS 语法模块 3 级。2021年12月24日。CR。URL: https://www.w3.org/TR/css-syntax-3/
[CSS-TEXT-4]
Elika Etemad 等人。CSS 文本模块 4 级。2023年10月20日。WD。URL: https://www.w3.org/TR/css-text-4/
[CSS-VALUES-3]
Tab Atkins Jr.; Elika Etemad. CSS 值与单位模块 3 级。2022年12月1日。CR。URL: https://www.w3.org/TR/css-values-3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS 值与单位模块 4 级。2023年12月18日。WD。URL: https://www.w3.org/TR/css-values-4/
[CSS-VARIABLES-1]
Tab Atkins Jr.. CSS 自定义属性与级联变量模块 1 级。2022年6月16日。CR。URL: https://www.w3.org/TR/css-variables-1/
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii. CSS 书写模式 4 级。2019年7月30日。CR。URL: https://www.w3.org/TR/css-writing-modes-4/
[CSS2]
Bert Bos 等人。层叠样式表 2.1 版 (CSS 2.1) 规范。2011年6月7日。REC。URL: https://www.w3.org/TR/CSS21/
[CSS22]
Bert Bos. 层叠样式表 2.2 版 (CSS 2.2) 规范。2016年4月12日。WD。URL: https://www.w3.org/TR/CSS22/
[CSS3TEXT]
Elika Etemad; Koji Ishii; Florian Rivoal. CSS 文本模块 3 级。2023年9月3日。CR。URL: https://www.w3.org/TR/css-text-3/
[CSSOM-1]
Daniel Glazman; Emilio Cobos Álvarez. CSS 对象模型 (CSSOM)。2021年8月26日。WD。URL: https://www.w3.org/TR/cssom-1/
[FETCH]
Anne van Kesteren. Fetch 标准。现行标准。URL: https://fetch.spec.whatwg.org/
[GRAPHITE]
Graphite 技术概述。2012年。URL: https://scripts.sil.org/cms/scripts/page.php?site_id=projects&item_id=graphite_techAbout
[HTML]
Anne van Kesteren 等人。HTML 标准。现行标准。URL: https://html.spec.whatwg.org/multipage/
[I18N-GLOSSARY]
Richard Ishida; Addison Phillips. 国际化术语表。2024年1月23日。说明文档。URL: https://www.w3.org/TR/i18n-glossary/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 标准。现行标准。URL: https://infra.spec.whatwg.org/
[OPENTYPE]
OpenType 规范。URL: http://www.microsoft.com/typography/otspec/default.htm
[OPENTYPE-FEATURES]
OpenType 特性注册表。URL: http://www.microsoft.com/typography/otspec/featurelist.htm
[RFC2119]
S. Bradner。RFC 中表示要求级别的关键词。1997年3月。最佳当前实践。URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC8081]
C. Lilley。"字体" 顶级媒体类型。2017年2月。建议标准。URL: https://www.rfc-editor.org/rfc/rfc8081
[UNICODE]
Unicode 标准。URL: https://www.unicode.org/versions/latest/
[UTS51]
Mark Davis; Ned Holbrook。Unicode Emoji。2023年9月5日。Unicode 技术标准 #51。URL: https://www.unicode.org/reports/tr51/tr51-25.html
[WEBIDL]
Edgar Chen; Timothy Gu。Web IDL 标准。现行标准。URL: https://webidl.spec.whatwg.org/

参考性参考文献

[CHARMOD-NORM]
Addison Phillips 等人。万维网字符模型: 字符串匹配。2021年8月11日。说明文档。URL: https://www.w3.org/TR/charmod-norm/
[CSS-DISPLAY-3]
Elika Etemad; Tab Atkins Jr.. CSS 显示模块 3 级。2023年3月30日。CR。URL: https://www.w3.org/TR/css-display-3/
[CSS-FONT-LOADING-3]
Tab Atkins Jr.. CSS 字体加载模块 3 级。2023年4月6日。WD。URL: https://www.w3.org/TR/css-font-loading-3/
[CSS-FONTS-3]
John Daggett; Myles Maxfield; Chris Lilley。CSS 字体模块 3 级。2018年9月20日。REC。URL: https://www.w3.org/TR/css-fonts-3/
[CSS-OVERFLOW-3]
Elika Etemad; Florian Rivoal。CSS 溢出模块 3 级。2023年3月29日。WD。URL: https://www.w3.org/TR/css-overflow-3/
[CSS-TRANSFORMS-1]
Simon Fraser 等人。CSS 变换模块 1 级。2019年2月14日。CR。URL: https://www.w3.org/TR/css-transforms-1/
[CSS3-CONDITIONAL]
David Baron; Elika Etemad; Chris Lilley。CSS 条件规则模块 3 级。2022年1月13日。CR。URL: https://www.w3.org/TR/css-conditional-3/
[IFT]
Chris Lilley; Garret Rieger; Myles Maxfield。增量字体传输。2023年5月30日。WD。URL: https://www.w3.org/TR/IFT/
[OPEN-FONT-FORMAT]
信息技术 — 音视频对象编码 — 第 22 部分:开放字体格式。URL: http://standards.iso.org/ittf/PubliclyAvailableStandards/c052136_ISO_IEC_14496-22_2009%28E%29.zip
[PFE-report]
Chris Lilley。渐进字体优化:评估报告。2020年10月15日。说明文档。URL: https://www.w3.org/TR/PFE-evaluation/
[TRUETYPE]
TrueType™ 参考手册。URL: https://developer.apple.com/fonts/TrueType-Reference-Manual/
[UAX29]
Josh Hadley。Unicode 文本分割。2023年8月16日。Unicode 标准附录 #29。URL: https://www.unicode.org/reports/tr29/tr29-43.html
[WINDOWS-GLYPH-PROC]
John Hudson。Windows 字形处理。URL: http://www.microsoft.com/typography/developers/opentype/default.htm

属性索引

名称 初始值 适用于 继承性 百分比 动画类型 语法顺序 计算值 媒体
font [ [ <'font-style'> || <font-variant-css2> || <'font-weight'> || <font-width-css3> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] | <system-family-name> 见各个属性 所有元素及文本 见各个属性 见各个属性 按语法 见各个属性
font-family [ <family-name> | <generic-family> ]# 依赖于用户代理 所有元素及文本 不适用 离散 按语法 列表,每个项为字符串和/或 <generic-family> 关键字
font-feature-settings normal | <feature-tag-value># normal 所有元素及文本 不适用 离散 按语法 按指定
font-kerning auto | normal | none auto 所有元素及文本 不适用 离散 按语法 按指定
font-language-override normal | <string> normal 所有元素及文本 不适用 离散 按语法 指定的字符串或关键词 none
font-optical-sizing auto | none auto 所有元素及文本 不适用 离散 按语法 指定的关键词
font-palette normal | light | dark | <palette-identifier> | <palette-mix()> normal 所有元素及文本 不适用 按计算值 按语法 指定的关键词、标识符或 <palette-mix()> 函数。<palette-mix()> 如果等效,则必须简化为单个关键词或标识符。
font-size <absolute-size> | <relative-size> | <length-percentage [0,∞]> | math medium 所有元素及文本 参照父元素的字体大小 按计算值类型 按语法 绝对长度
font-size-adjust none | <number [0,∞]> none 所有元素及文本 不适用 按计算值类型 按语法 数字或关键词 none
font-style normal | italic | oblique <angle [-90deg,90deg]>? normal 所有元素及文本 不适用 按计算值类型;normal 动画为 oblique 0deg 按语法 指定的关键词,加上角度(如有)
font-synthesis none | [ weight || style || small-caps || position] weight style small-caps position 所有元素及文本 不适用 离散 按语法 指定的关键词
font-synthesis-position auto | none auto 所有元素及文本 不适用 离散 按语法 指定的关键词
font-synthesis-small-caps auto | none auto 所有元素及文本 不适用 离散 按语法 指定的关键词
font-synthesis-style auto | none auto 所有元素及文本 不适用 离散 按语法 指定的关键词 视觉
font-synthesis-weight auto | none auto 所有元素及文本 不适用 离散 按语法 指定的关键词 视觉
font-variant normal | none | [ [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ] || [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ] || [ stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) ] || [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero ] || [ <east-asian-variant-values> || <east-asian-width-values> || ruby ] || [ sub | super ] || [ text | emoji | unicode ] ] normal 所有元素及文本 不适用 离散 按语法 按指定
font-variant-alternates normal | [ stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) ] normal 所有元素及文本 不适用 离散 按语法 按指定
font-variant-caps normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps normal 所有元素及文本 不适用 离散 按语法 按指定
font-variant-east-asian normal | [ <east-asian-variant-values> || <east-asian-width-values> || ruby ] normal 所有元素及文本 不适用 离散 按语法 按指定
font-variant-emoji normal | text | emoji | unicode normal 所有元素及文本 不适用 离散 按语法 指定的关键词
font-variant-ligatures normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ] normal 所有元素及文本 不适用 离散 按语法 按指定
font-variant-numeric normal | [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero ] normal 所有元素及文本 不适用 离散 按语法 按指定
font-variant-position normal | sub | super normal 所有元素及文本 不适用 离散 按语法 按指定
font-variation-settings normal | [ <opentype-tag> <number>]# normal 所有元素及文本 不适用 (参见详细描述) 按语法 关键词 normal 或列表,每个项为字符串与数字配对
font-weight <font-weight-absolute> | bolder | lighter normal 所有元素及文本 不适用 按计算值类型 按语法 数字,见下文
font-width normal | <percentage [0,∞]> | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded normal 所有元素及文本 未解析 按计算值类型 按语法 百分比,见下文

@font-face 描述符

名称 初始值
ascent-override normal | <percentage [0,∞]> normal
descent-override normal | <percentage [0,∞]> normal
font-display auto | block | swap | fallback | optional auto
font-family <family-name> N/A
font-feature-settings normal | <feature-tag-value># normal
font-language-override normal | <string> normal
font-named-instance auto | <string> auto
font-style auto | normal | italic | oblique [ <angle [-90deg,90deg]>{1,2} ]? auto
font-variation-settings normal | [ <string> <number>]# normal
font-weight auto | <font-weight-absolute>{1,2} auto
font-width auto | <'font-width'>{1,2} auto
line-gap-override normal | <percentage [0,∞]> normal
src <font-src-list> N/A
unicode-range <urange># U+0-10FFFF

@font-feature-values 描述符

名称 初始值
font-display auto | block | swap | fallback | optional auto

@font-palette-values 描述符

名称 初始值
base-palette light | dark | <integer [0,∞]> N/A
font-family <family-name># N/A
override-colors [ <integer [0,∞]> <color> ]# N/A

IDL 索引

[Exposed=Window]
interface CSSFontFaceRule : CSSRule {
  readonly attribute CSSStyleDeclaration style;
};

partial interface CSSRule {  const unsigned short FONT_FEATURE_VALUES_RULE = 14;
};
[Exposed=Window]
interface CSSFontFeatureValuesRule : CSSRule {
  attribute CSSOMString fontFamily;
  readonly attribute CSSFontFeatureValuesMap annotation;
  readonly attribute CSSFontFeatureValuesMap ornaments;
  readonly attribute CSSFontFeatureValuesMap stylistic;
  readonly attribute CSSFontFeatureValuesMap swash;
  readonly attribute CSSFontFeatureValuesMap characterVariant;
  readonly attribute CSSFontFeatureValuesMap styleset;
};

[Exposed=Window]
interface CSSFontFeatureValuesMap {
  maplike<CSSOMString, sequence<unsigned long>>;
  undefined set(CSSOMString featureValueName,
         (unsigned long or sequence<unsigned long>) values);
};

[Exposed=Window]interface CSSFontPaletteValuesRule : CSSRule {
  readonly attribute CSSOMString name;
  readonly attribute CSSOMString fontFamily;
  readonly attribute CSSOMString basePalette;
  readonly attribute CSSOMString overrideColors;
};

问题索引

正斜体和负斜体在垂直书写模式下应朝哪个方向倾斜?我们如何在另一维度实现倾斜 (垂直书写模式需要)?
fallbackoptional 可能会导致同一个字体家族中的一些字形被使用, 而另一些则需要回退,这会导致字体看起来像“赎金条”。或许要求同一个家族的所有字体表现一致(要么都替换,要么都回退)? 另请参阅 @font-feature-values 控制字体家族的行为。
stream 中根据字体类型加载字体。
选择倾向于使用斜体而非普通字体的阈值 应低于平均角度
添加更多示例和图片。