可变字体指南

**可变字体**是 OpenType 字体规范的演变,它使许多不同的字体变体能够合并到单个文件中,而不是为每个宽度、粗细或样式都使用单独的字体文件。它们允许您通过 CSS 和单个@font-face引用访问给定字体文件中包含的所有变体。本文将为您提供开始使用可变字体所需的所有信息。

**注意:**要在您的操作系统上使用可变字体,您需要确保它是最新的。例如,Linux 操作系统需要最新的 Linux Freetype 版本,macOS 10.13(High Sierra)之前的版本不支持可变字体。如果您的操作系统不是最新的,您将无法在网页或 Firefox 开发者工具中使用可变字体。

可变字体:它们是什么,以及它们有何不同

为了更好地理解可变字体与众不同之处,值得回顾一下非可变字体是什么样的以及它们如何比较。

标准(或静态)字体

过去,字体会被制作成几个单独的字体,每个字体代表一个特定的宽度/粗细/样式组合。因此,您将有单独的文件用于“Roboto Regular”、“Roboto Bold”和“Roboto Bold Italic”——这意味着您最终可能会有 20 或 30 个不同的字体文件来表示完整的字体(对于具有不同宽度的较大型字体,这可能是几倍)。

在这种情况下,要在网站上将字体用于正文内容的典型使用,您至少需要四个文件:常规、斜体、粗体和粗体斜体。如果您想添加更多粗细,例如用于标题的较轻粗细或用于额外强调的较重粗细,则意味着需要更多文件。这会导致更多 HTTP 请求,以及下载更多数据(通常每个文件约 20k 或更多)。

可变字体

使用可变字体,所有这些排列都可以包含在一个文件中。该文件将比单个字体更大,但在大多数情况下,它的大小与您可能为正文内容加载的 4 个文件的大小相同或更小。选择可变字体的优势在于,您可以访问所有可用的粗细、宽度和样式范围,而不是仅限于您之前单独加载的少数几个。

这允许使用常见的排版技术,例如为不同大小的标题设置不同的粗细,以提高每个大小的可读性,或者在数据密集型显示中使用稍微窄一点的宽度。作为比较,在杂志的排版系统中,通常使用 10-15 个或更多不同的粗细和宽度组合贯穿整个出版物——提供的样式范围比目前网络上的典型样式(或者仅出于性能原因而实际上可行的样式)要广泛得多。

关于字体系列、粗细和变体的说明

您可能会注意到,我们一直在讨论为每种粗细和样式(即粗体、斜体和粗斜体)准备一个特定的字体文件,而不是依赖浏览器来合成它们。这样做的原因是,大多数字体对更粗的粗细和斜体都有非常特定的设计,这些设计通常包含完全不同的字符(例如,小写字母“a”和“g”在斜体中通常差别很大)。为了最准确地反映字体设计并避免浏览器之间以及它们如何合成不同样式的差异,在使用非可变字体时,加载所需的特定字体文件更为准确。

您也可能会发现,一些可变字体被分成两个文件:一个用于正体及其所有变体,另一个包含斜体变体。有时这样做是为了在不需要或不使用斜体的情况下减小整体文件大小。在所有情况下,仍然可以使用通用的font-family名称链接它们,以便您可以使用相同的font-family和适当的font-style来调用它们。

介绍“变化轴”

新的可变字体格式的核心概念是变化轴,它描述了字体设计该特定方面的允许范围。因此,“粗细轴”描述了字形可以有多细或多粗;“宽度轴”描述了它们可以有多窄或多宽;“斜体轴”描述了斜体字形是否存在以及是否可以相应地打开或关闭,等等。请注意,轴可以是范围或二元选择。粗细的范围可能为 1-999,而斜体可能是 0 或 1(关闭或打开)。

如规范中所定义,有两种轴:注册自定义

  • 注册轴是指最常遇到的轴,并且足够常见,以至于规范的作者认为值得标准化。目前注册的五个轴是粗细、宽度、倾斜、斜体和视觉尺寸。W3C 已着手将它们映射到现有的 CSS 属性,并在一种情况下引入了一个新的属性,您将在下面看到。
  • 自定义轴是无限的:字体设计师可以定义和确定他们喜欢的任何轴,并且只需要为它提供一个四字母的标签来识别它在字体文件格式本身中的位置。您可以使用这些四字母标签在 CSS 中指定变化轴上的某个点,如下面的代码示例所示。

注册轴和现有的 CSS 属性

在本节中,我们将通过示例和相应的 CSS 演示定义的五个注册轴。在可能的情况下,都包含标准语法和低级语法。低级语法(font-variation-settings)是第一个用于测试可变字体支持的早期实现的机制,并且需要利用超出五个注册轴的新轴或自定义轴。但是,W3C 的意图是,当其他属性可用时,不应使用此语法。因此,在任何可能的情况下,都应使用相应的属性,仅在使用font-variation-settings的低级语法来设置其他方式不可用的值或轴时。

备注

  1. 使用font-variation-settings时,请注意轴名称区分大小写。注册的轴名称必须小写,自定义轴必须大写。例如
    css
    font-variation-settings:
      "wght" 375,
      "GRAD" 88;
    
    wght(粗细)是一个注册轴,而GRAD(等级)是一个自定义轴。
  2. 如果您已使用font-variation-settings设置了值,并且想要更改其中一个值,则必须重新声明所有值(与使用font-feature-settings设置 OpenType 字体特性时相同)。您可以使用CSS 自定义属性(CSS 变量)来解决此限制,方法是为各个值设置自定义属性,并修改各个自定义属性的值。本指南末尾提供了示例代码。

粗细

粗细(由wght标签表示)定义了字形笔划可以有多细或多粗(用典型的印刷术语来说,就是轻或重)的设计轴。在 CSS 中,长期以来一直可以通过font-weight属性指定这一点,该属性采用 100 到 900 的数值(以 100 为增量),以及诸如normalbold之类的关键字,这些关键字是其相应数值的别名(在本例中为 400 和 700)。在处理非可变字体或可变字体时,这些仍然适用,但对于可变字体,现在 1 到 1000 的任何数字都是有效的。

需要注意的是,目前在@font-face声明中无法将可变字体的变化轴上的特定点“映射”到关键字bold(或任何其他关键字)。这通常可以很容易地解决,但需要在编写 CSS 时增加一个步骤。

css
font-weight: 375;

font-variation-settings: "wght" 375;

以下实时示例的 CSS 可以进行编辑,以允许您使用字体粗细值。

宽度

宽度(由wdth标签表示)定义了字形可以有多窄或多宽(用印刷术语来说,就是紧缩或扩展)的设计轴。这通常在 CSS 中使用font-stretch属性设置,其值为高于或低于“normal”(100%)的百分比,任何大于 0 的数字在技术上都是有效的——尽管范围更有可能接近 100% 标记,例如 75%-125%。如果提供的数值超出字体中编码的范围,浏览器应在允许的最接近的值处渲染字体。

注意:使用font-variation-settings时不使用 % 符号。

css
font-stretch: 115%;

font-variation-settings: "wdth" 115;

以下实时示例的 CSS 可以进行编辑,以允许您使用字体宽度值。

斜体

斜体(ital)轴可以在[0-1]范围内设置,其中0表示“非斜体”,0.5表示“半斜体”,1表示“完全斜体”。斜体设计通常包含与其正体对应物截然不同的字形,因此在从正体到斜体的过渡中,通常会发生一些字形(或字符)替换。斜体和倾斜通常可以互换使用,但实际上却大不相同。倾斜在此上下文中使用术语slant(请参见下面的部分)定义,并且字体通常会具有其中一个,但不会同时具有两者。

在 CSS 中,斜体和倾斜都使用font-style属性应用于文本。另请注意font-synthesis: none;的引入——这将阻止浏览器意外地应用变化轴和合成的斜体。这也可以用来防止伪粗体。

css
font-style: italic;

font-variation-settings: "ital" 1;

font-synthesis: none;

以下实时示例的 CSS 可以进行编辑,以允许您使用字体斜体。

倾斜

倾斜(由slnt标签表示),或者通常称为“倾斜”——与真正的斜体不同,因为它会更改字形的角度,但不会执行任何字符替换。它也是可变的,因为它表示为数值范围。这允许字体在倾斜轴上的任何位置变化。允许的范围为 -90 到 90 度。

可以控制倾斜的两个属性是font-stylefont-variation-settings。以下两个属性声明是相同的

font-style: oblique 14deg;

font-variation-settings: "slnt" -14;

优先使用font-style属性而不是font-variation-settings属性。使用font-variation-settings属性时不使用deg关键字。此外,在font-variation-settings属性的情况下,正角度表示逆时针倾斜。

在以下实时示例中,您可以调整倾斜度。

css
@font-face {
  font-family: "SlantFont";
  font-style: oblique -15 15;
  src: url("https://mdn.github.io/shared-assets/fonts/font_with_slant_axis.woff2")
    format("woff2");
}

p {
  font-family: "SlantFont";
}

.font-style {
  font-style: oblique 5deg;
}

.font-variation {
  font-variation-settings: "slnt" -5;
}

.adjustable {
  font-variation-settings: "slnt" var(--slant-angle);
}

视觉尺寸

这是数字字体和 CSS 中的新事物,但却是金属印刷设计和创建中一个延续了几个世纪的技术。视觉尺寸是指根据物理尺寸改变字形整体笔划粗细的做法。如果尺寸非常小(例如相当于 10 或 12px),则字符将具有整体更粗的笔划,并且可能还有其他一些小的修改,以确保它能够在物理上更小的尺寸下再现并可读。相反,当使用更大的尺寸(如 48 或 60px)时,粗细笔划的权重可能会有更大的差异,使字体设计更符合最初的意图。

虽然这最初是为了补偿油墨和纸张印刷过程(小尺寸下的非常细的线条通常无法打印,使字形出现断裂的外观),但在补偿屏幕质量和物理尺寸渲染时,它可以很好地转换为数字显示。

视觉尺寸值通常旨在自动应用于相应的font-size,但也可以使用低级font-variation-settings语法进行操作。

有一个新的属性font-optical-sizing用于在 CSS 中支持可变字体。使用font-optical-sizing时,唯一允许的值是autonone——因此此属性仅允许打开或关闭视觉尺寸。但是,当使用font-variation-settings: 'opsz' <num>时,您可以提供一个数值。在大多数情况下,您希望将font-size(类型渲染的物理尺寸)与opsz值(当使用auto时,视觉尺寸的预期应用方式)相匹配。提供特定值的选项是为了,如果需要为了可读性、美观或其他原因覆盖默认值,则可以应用特定值。

css
font-optical-sizing: auto;

font-variation-settings: "opsz" 36;

以下实时示例的 CSS 可以进行编辑,以允许您使用视觉尺寸值。

自定义轴

自定义轴就是这样:它们可以是字体设计师想象的任何设计变化轴。可能有一些会变得相当普遍——甚至会被注册——但只有时间才能证明。

等级

等级可能会成为更常见的自定义轴之一,因为它在字体设计中有着悠久的历史。设计不同等级的字体通常是对预期用途和印刷技术的反应。“等级”一词指的是字体设计的相对粗细或密度,但它与传统的“粗细”不同,因为文本占据的物理空间不会改变,因此更改文本等级不会改变文本或周围元素的整体布局。这使得等级成为一个有用的变化轴,因为它可以在不导致文本本身重新流动的情况下进行变化或动画。

css
font-variation-settings: "GRAD" 88;

以下实时示例的 CSS 可以进行编辑,以允许您使用字体等级值。

使用可变字体:@font-face 更改

加载可变字体的语法与任何其他网络字体非常相似,但有一些值得注意的差异,这些差异是通过对现代浏览器中可用的传统@font-face语法进行升级提供的。

基本语法相同,但可以指定字体技术,并且可以提供诸如font-weightfont-stretch之类的描述符的允许范围,而不是根据要加载的字体文件命名。

标准正体(罗马)字体的示例

css
@font-face {
  font-family: "MyVariableFontName";
  src: url("path/to/font/file/myvariablefont.woff2") format("woff2-variations");
  font-weight: 125 950;
  font-stretch: 75% 125%;
  font-style: normal;
}

在这种情况下,normal值表示当样式规则中的font-family属性为MyVariableFontNamefont-style属性为normal时,应使用此字体文件。由于0deg的存在,oblique 0degoblique 0deg 20deg值也表示字体具有正常的正体字形。

仅包含斜体而不包含正体字符的字体的示例

css
@font-face {
  font-family: "MyVariableFontName";
  src: url("path/to/font/file/myvariablefont.woff2") format("woff2-variations");
  font-weight: 125 950;
  font-stretch: 75% 125%;
  font-style: italic;
}

在这种情况下,italic值表示当样式规则中的font-family属性为MyVariableFontNamefont-style属性为italic时,应使用此字体文件。oblique 14deg值也表示字体具有斜体字形。

包含倾斜(倾斜)轴的字体的示例

css
@font-face {
  font-family: "MyVariableFontName";
  src: url("path/to/font/file/myvariablefont.woff2") format("woff2-variations");
  font-weight: 125 950;
  font-stretch: 75% 125%;
  font-style: oblique 0deg 12deg;
}

在这种情况下,oblique 0deg 12deg 值表示当样式规则中的 font-family 属性为 MyVariableFontNamefont-style 属性为斜体,且角度在 0 到 12 度(包含)之间时,应该使用此字体文件。

注意:并非所有浏览器都已实现字体格式的完整语法,因此请仔细测试。所有支持可变字体的浏览器,如果您将格式设置为仅文件格式而不是格式变体(即 woff2 而不是 woff2-variations),仍然会渲染它们,但如果可能,最好使用正确的语法。

注意:font-weightfont-stretchfont-style 提供值范围将阻止浏览器在您使用相应属性(即 font-weightfont-stretch)时尝试渲染超出该范围的轴,但不会阻止您通过 font-variation-settings 提供无效值,因此请谨慎使用。

与旧版浏览器配合使用

可以使用 CSS 功能查询检查可变字体支持(请参阅 @supports),因此可以在生产环境中使用可变字体,并在功能查询块内限定调用可变字体的 CSS。

css
h1 {
  font-family: some-non-variable-font-family;
}

@supports (font-variation-settings: "wdth" 115) {
  h1 {
    font-family: some-variable-font-family;
  }
}

示例页面

以下示例页面展示了两种不同的 CSS 结构方式。第一个示例尽可能使用标准属性。第二个示例使用 CSS 自定义属性为 font-variation-settings 字符串设置值,并展示了如何通过覆盖单个变量而不是重写整个字符串来更轻松地更新单个变量值。请注意 h2 上的悬停效果,它只更改了等级轴自定义属性的值。

资源