图解CSS: 变量字体
Web排版和传统的印刷排版之间的差距不是一点点,而且Web排版一直以来都令Web开发者感到头痛,由其是Web中的字体。或许你在平时开发Web页面或Web应用的时候已经发现在Web上需要渲染一些更具艺术风格的字体,或者希望在响应式Web排版的设计中让文字能根据断点做出相应的响应等。虽然通过一些技术手段可以实现类似的效果,但同时也会造成许多新的问题产生。幸运的是,2015年开始推出了OpenType字体格式,以一些非常显著的方式改变了开发者面临的实际困难。他们有能力在较小的文件下为Web带来更丰富的排版性,但随着新的可能性和优势,新的挑战和复杂性也随之出现。那么,OpenType字体的引入之后会给Web带来什么样的变化?我们又应该在Web中怎么使用?接下来,我们一起来探讨这方面的话题。
什么是可变字体?
可变字体是数字时代的一种字体技术。@John Hudson对可变字体是这样解说的:
可变字体文件是一种字体文件,它的行为类似于多种字体。
传统上,大多数网站使用的字体都属性同一字体族。每种字体都存储在一个单独的文件中,并具有一组独特的属性,比如字宽、字重和样式。现在,在一个OpenType变量字体文件中,可以存储多种字体样式,也就是说,可变字体将字体所有这些变化都存储在一个字体文件中,并且字体的大小相对较小。与静态字体相比,可变字体允许你在一个范围内使用字体的字宽、字重和样式等。
例如,大多数字体族都包含一组字体,这些字体具有100~900
的不同字重。可变字体提供了在指定范围内使用任何字重的能力。因此,如果在你的网站上使用font-weight: 700
是一个最佳的效果,那么你就可以使用字重为700
的字体。
另外一点就是,可变字体文件要比静态字体文件小得多,这是因为可变字体中每个字符只有一个结构。构建此结构的点具有可操作性,比如可以移动这些点,从而创建出另一个权重的指令。然后插入各个样式,这意味着它们是在浏览器内动态绘制的。这也使得在半粗体和粗体之间生成不同的样式成为可能。
插值可以在不同的轴上发生变化,比如字重的轴上。这样可以创造一个具有层次感的字体样式。还有一些命名的实例,比如regular
或font-weight: 700
,都可以工作,但你还可以选择两者之间的任何设计。
可变字体可以包含多个轴。你可以添加一个字宽的轴到字重轴上,并获得更多的风格。由@Dalton Maag设计的Venn,在这些例子中使用的可变字体,支持300~800
的字重和75%~125%
的字宽。这意味着,如果你把这些范围(500×50
)相乘,就可以得到25000
种风格的Venn,而且文件大小约112kb
,这已经是非常完美了。
在可变字体中,常见的“注册轴”有:字宽(width
)、字重(weight
)、斜度(slant
)、**斜体(italic
)和光学尺寸(optical size
)**等,但注册轴是可以扩展的,这样设计师可以定义他们自己所需的自定义轴,并允许他们想要创建的任何类型的变化。
如何处理可变字体?
可变字体的处理主要取决于字体的设计。类型设计器提供了各种轴,这些轴描述了哪些属性是可变的,以及这些属性的允许范围。可变字体可以有两种类型的轴:注册轴和自定义轴。
注册轴是最常见的轴,并且是显式定义的。在可变字体设计中有五个注册轴,包括字重、字宽、斜体、倾斜和光学尺寸。每个注册轴都有一个对应的四个字母的标记,可以映射到现有的CSS属性。
注册轴 | 字母标记 | CSS属性 |
---|---|---|
Weight | wght |
font-weight |
Width | wdth |
font-stretch |
Italic | ital |
font-style |
Slant | slnt |
font-style |
Optical Size | opsz |
font-optical-sizing |
注意:注册轴不是必须的特性。包含哪些注册轴主要取决于字体设计器。
除了注册轴之外,字体设计器还可以包含自定义轴。自定义轴让可变字体变得更具创造性,因为不限制自定义轴的范围、定义或数量。与注册轴类似,自定义轴具有相应的四个字母标记。但是,自定义轴的字母标记必须是大写的。例如,你定义了一个注册轴是grade
,其对应的字母标记是 GRAD
。
接下来,我们来看看这五个已注册的轴以及如何使用它们。
字重(Weight)
五个注册轴中可能属字重最明显,几乎所有的字体都至少设计普通(Regular)和粗体(Bold),而且还有像更轻(Lighter)、更薄(Thinner)和更粗(Bolder)等极端现象。对于可变字体,可以使用CSS的font-weight
属性提供一个介于为字体定义的最小值和最大值之间的数字,而不仅仅是一个关键词(比如normal
或bold
)。根据OpenType规范,对于任何给定的字体,400
对应的是normal
,但是在实践中,你将看到目前它可以根据字体的不同而有很大的变化。
p {
font-weight: 425;
}
strong {
font-weight: 675;
}
如果要使用变化轴,就需要使用CSS的font-variation-settings
属性。比如像下面这样使用:
:root {
--text-vf-wght: 400;
}
p {
font-variation-settings: "wght" var(--text-vf-wght);
}
在上面折例子中,wght
对应的是CSS的font-weight
,而var(--text-vf-wght)
是其值,即400
。
字宽(Width)
字体设计的另一个常见变化是字宽。它通常被称为压缩(Condensed)或扩展(Expanded)。根据相关规范可得知,100
对应的是normal
字宽,其有效值是1~1000
。和字体权重(字重)类似,在CSS中也有相应的标准属性font-stretch
,并以百分比的形式表示。在早期阶段,许多类型设计人员不一定遵守这个标准的数值范围,所以在CSS中看起来有点奇怪。但是3%~5%
的范围仍然有效的,即使在这种情况下,5%
实际上是正常的宽度。
在Web的使用中,可以像字宽类似有两种方式。第一种是使用CSS标准属性font-stretch
:
p {
font-stretch: 89%;
}
也可以像下面这样使用font-variation-settings
属性:
:root {
--text-vf-wdth: 95;
}
p {
font-variation-settings: 'wdth' var(--text-vf-wdth);
}
斜体(Italic)
有的时候一些字体是不包含斜体风格的类型,但这种类型有的时候却又或多或少有所需。在大多数情况下,它是一个布尔值0
或1
。通常小写字母a
或g
的斜体形式略有不同。虽然有可能有一个范围,而不是严格意义上的0
或1
,但关闭或打开场景可能是你遇到的最常见的情况。不幸的是,尽管它的目的是和CSS的font-style:italic
相匹配,但这是浏览器尚未完全实现的一个方面,因此我们不得不依赖font-variation-settings
属性。
:root {
--text-ital: 0;
}
body {
font-variation-settings: 'ital' var(--text-ital);
}
em {
--text-ital: 1;
}
倾斜(Slant)
可变字体中倾斜轴类似于斜体,但在两个关键方面有所不同。首先,它在一个角度范围内做倾斜,根据OpenType规范,这个角度的范围应该是“大于-90
且小于+90
”,其次,它不包括字形替换。通常与无衬线字体设计相关,它允许指定范围内的任何值。如果你使用的字体只有一个倾斜轴,没有斜体,你也可以使用CSS的font-style
,就像下面这样:
em {
font-style: oblique 12deg;
}
如果两个轴都有(倾斜轴和斜体轴),则需要使用font-variation-settings
属性:
:root {
--text-slnt: 0;
}
body {
font-variation-settings: 'slnt' var(--text-slnt);
}
em {
--text-slnt: 12;
}
光学尺寸(Optical Size)
光学上色是印刷设计的一个概念,它的目标是在小字体上达到最佳的可读性,在大字体上达到最佳的个性化。在金属字体时代,一切都是为特定的字体大小而优化的。通过数字化,你可以创造出一个适合所有尺寸的设计结果却丢失了。现在它又重新回到可变字体中。例如,小字体的笔画可能会更粗,这意味着有更少的对比,同时让文本更易读;另一方面,在更大的尺寸上,可以看到更多的细节,因此有更多的对比度。这种变化可以逐渐发生,再一次,只有一个字体文件被使用。
在可变字体中,这个轴的数值应该与font-size
相匹配,并引入了一个新的CSS属性font-optical-sizing
,该属性的默认值是auto
。你也可以强制关闭它,或者可以使用font-variation-settings
属性显式设置值。
body {
font-optical-sizing: auto;
}
或者:
:root {
--text-opsz: 16;
}
body {
font-variation-settings: 'opsz' var(--text-opsz);
}
h1 {
--text-opsz: 48;
font-size: 3em;
}
自定义轴
可变字体到目前为止只有五个注册轴,但是类型设计器也可以创建它们自己的轴。字体设计的任何方面都可能成为一个轴。比如衬线字体(serif
)或小写x
字母的高度(x-height
),以及其他更具创意的方面,比如重图片。
我们来看一个示例。字体的“等级”(grade
)概念,其最初只是为了补尝不同类型的纸张和印刷机上的油墨增益,从而在视觉上纠正不同的工作流程,并使每个人都能看到相同的字体。其概念是在不改变间距的情况下改变字体的重量(Weight
)。将其作为一个变量轴在很多方面都很有用。创建一个高对比度模式,使文本变得更重,而不需要重新流动,可以使文本在线线较暗的情况下或在设计暗黑模式时更清晰。另外在响应分辨率较低的屏幕时,它也可以派上用场,因为在低分辨率屏幕上,类型很容易变得有点细长。
在使用自定义轴时,四个字母需要使用大写方式。比如:
:root {
--text-GRAD: 0;
}
body {
font-variation-settings: 'GRAD' var(--text-GRAD);
}
body.dark {
--text-GRAD: 0.5;
}
运用多个注册轴
如果可变字体同时具备多个注册轴,那么我们在实际使用的时候,可以使用font-variation-settings
来同时在文本上运用,比如像下面这样:
:root {
--text-vf-wght: 400;
--text-vf-wdth: 95;
--text-vf-slnt: 9;
--text-vf-ital: 0;
--text-vf-opsz: 80;
}
p {
font-variation-settings:"wght" var(--text-vf-wght), "wdth" var(--text-vf-wdth), "slnt" calc( var(--text-vf-slnt) * -1), "ital" var(--text-vf-ital), "opsz" var(--text-vf-opsz);
}
效果如下:
前面也提到过了,可变字体已知的五个注册轴有相应的标准CSS属性支持,比如:
p {
font-variation-settings:"wght" var(--text-vf-wght), "wdth" var(--text-vf-wdth), "slnt" calc( var(--text-vf-slnt) * -1), "ital" var(--text-vf-ital), "opsz" var(--text-vf-opsz);
}
也可以写成:
p {
font-weight: var(--text-vf-wght); // 对应“wght”注册轴
font-stretch: calc(var(--text-vf-wdth) * 1%); // 对应的是"wdth"注册轴
font-style: oblique calc(var(--text-vf-slnt) * 1deg); //对应的是"slnt"注册轴
font-style: italic; // 对应的是"ital"注册轴
font-optical-sizing: auto; //对应的是"opsz"注册轴
}
注意,按照CSS的样式规则,如果同一代码块中有相同的CSS属性,那么后者将会替代前者。而且font-style:italic
在不同的浏览器下以及不同的字体之间效果都有一定的差异。如果你使用可变字体,建议是代码中使用font-variation-settings
更妥当一些。
同时,在可变字体中很多注册轴都有一个区间值,比如上面示例中的wght
它的区间是100~700
,slnt
的区间是0~15
,在CSS的属性运用中,可以同时赋两个值,第一个是最低值,第二个是最高值。因此,看到像下面这样的代码无需感到惊奇:
@font-face {
font-family: 'MyVariableFontName';
src:
'path/to/font/file/myvariablefont.woff2' format('woff2-variations');
font-weight: 100 700;
font-stretch: 85% 100%;
font-style: oblique 0deg 15deg
}
注意:
font-variation-settings
属性是 CSS Fonts Module Level 4 规范中一个新特性,如果你对该属性感兴趣的话,还可以阅读《字体变体font-variation-*
》一文。
可变颜色字体
可变颜色字体是一种较新的技术,有很多东西值得我们探索。在这里不会对可变颜色字体做深入的介绍,只是在此抛砖引玉,感兴趣的同学可以自行探讨。
可变颜色字体是什么呢?在解释之前,先上张图:
看到上图是不是觉得很神奇。
上图的效果就是我们所要说的可变颜色字体,即可变字体是一种带有彩色形状或图标的定制字体。来个小示例:
如果你对可变颜色字体感兴趣的话,可以阅读下面这些文章:
- Variable Color Fonts
- Color fonts! WTF?
- What Are Color Fonts?
- Color Fonts Trend: What They Are & How To Use Them
- Rocher Color: making a variable color font
- A tiny guide to Variable Fonts & Color Fonts
另外, @shadeed9的《Creating a Variable Color Font From Scratch》一文中有一节内容专门介绍了可变颜色字体,以及用一个简单的Demo,介绍了如何制作可变颜色字体。
如何在Web上使用可变字体
通过前面的介绍,我们对可变字体有了一定的了解,接下来通过实例向大家介绍如何在Web中使用可变字体。
Step01:查找可用的可变字体
可变字体相对来说是一项较新的技术,而且可变字体是一种特定的字体。所以在Web中使用可变字体时需要先确认该字体是不是可变字体。如果你自己没有可变字体,而又想体验一下可变字体相关技术,那么@Nick Sherman的 **v-fonts.com**是一个不错的选择。在这个网站上你可以找到很多可用的可变字体,而且还是开源的。另外@Indra Kupferschmid还整理了一份可变字体列表,你也可以从这里获取。
除些之外,Google Fonts提供了很多可变字体,你只需要在Google Fonts页面中搜索时选择“Show only variable fonts”选项,那么过滤出来的字体都是可变字体:
当你在右上角选择带有“Variable”标签的字体时,你将在样式列表的底部找到可变字体版本:
接下来创建自定义样式,在页面中你就可以获取到嵌入Web页面的代码:
代码如下:
<link href="https://fonts.googleapis.com/css2?family=Oswald:wght@200;300;400;469;500;600;681;700&display=swap" rel="stylesheet">
你可以根据自己的需要去自定义样式,比如wght
(即font-weight
)的值。
Step02: 在样式表中集成可变字体
正如第一步所示,如果你使用的是Google Fonts,你最终可以获取到一个<link>
标签,同时指定了你所需要的字体以及你自定义的相关参数,比如:
<link href="https://fonts.googleapis.com/css2?family=Oswald:wght@200;300;400;469;500;600;681;700&display=swap" rel="stylesheet">
除了<link>
方式之外,还可以是CSS的@import
方式:
<style>
@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@200;300;400;469;500;600;681;700&display=swap');
</style>
这样你在CSS中就可以使用Oswald
这个可变字体:
p {
font-family: 'Oswald';
font-weight: 681;
}
对于可变字体的集成并不是件复杂的事情,你可以尝试着在浏览器的地址栏粘贴下面这段代码:
https://fonts.googleapis.com/css2?family=Oswald:wght@200;300;400;469;500;600;681;700&display=swap
你会发现对应的代码中都是@font-face
代码块。不同的是,指定可变字体时,@font-face
和以往我们使用的方式略有不同。比如我们以往使用@font-face
可能会像下面这样:
@font-face {
font-family: 'YourWebFontName';
src: url('YourWebFontName.eot'); /* IE9 Compat Modes */
src: url('YourWebFontName.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('YourWebFontName.woff') format('woff'), /* Modern Browsers */
url('YourWebFontName.ttf') format('truetype'), /* Safari, Android, iOS */
url('YourWebFontName.svg#YourWebFontName') format('svg'); /* Legacy iOS */
}
在引用可变字体时,@font-face
像下面这样:
@font-face {
font-family: "Family Name";
src: url("YourVariableFontName.woff2")
format("woff2 supports variations"), url("YourVariableFontName.woff2")
format("woff2-variations");
font-weight: [low] [high];
font-stretch: [low]% [high]%;
font-style: oblique [low]deg [high]deg;
}
你可能已经注意到的第一个不同之处就是src
,src
指向了同一个字体文件,这主要是@font-face
的语法规则做出了调整,只不过目前有些浏览器还没有跟进而以。这种语法相对来说更为灵活了,因为我们除了可变字体之外,可能还会使用可变颜色字体。因此第一个入口使用woff2 supports variations
的格式化(format
)参数来指定支持两种(可变字体和可变颜色字体)字体。一旦浏览器理解了这种语法,它们就会停止解析src
行。现在,他们将跳过这一步,使用woff2-variations
格式来实现第二步,所有当前支持可变字体的浏览器都能理解这一点。
对于font-weight
、font-stretch
和font-style
等属性为什么这样指定值,在前面已经有介绍,这里不再做相关的阐述。但有一点需要注意,如果还有一个斜体轴(或者只有一个斜体轴而没有倾斜轴),此时最好完全忽略font-style
样式。
在@font-face
显式指定可变字体的字重轴(wght
)、字宽轴(wdth
)、斜体轴(ital
)和倾斜轴(slnt
)是可以起到保护作用的,可以告诉浏览器,如果CSS中使用的值超出了这个范围浏览器应该如何处理。比如,font-weight
指定的范围是300~700
,但你在使用font-weight
时显式的设置了值为100
,这个时候浏览器会将font-weight
渲染为300
,而不会渲染成100
。值得注意的是,这个范围只适用于CSS的标准属性,如果你使用font-variation-settings
来指定字体权重时(比如 font-variation-settings: "wght" 100
),浏览器会认为你是这方面的专家,因此会尝试着合成,即使它超出了正常范围。
Step03:找出可变字体的轴和范围值
每个可变字体的细节都有所不同,在Web上使用可变字体之前,必须要对可变字体所支持的细节有所了解。如果你有可变字体文件,那么可以使用@Roel Nieskens的 WakamaiFondue.com 网站来做检测:
你只需要把本地的字体文件拖到这个网页中,那么 WakamaiFondue.com 就会自动给你生成一份有关于该可变字体相关细节的报告,显示字体的特性、支持的语言、文件大小、字形数量和字体支持的所有可变轴,并显示低/高/默认值。还会生成对应的样式:
您甚至还获得了一个类型测试案例和一些滑动器,以允许您使用不同的轴,并做出相应的调整。
请注意坐标轴、值和缺省值。我们在编写CSS时需要这些信息。如果你本地没有可变字体,而且又想体验一下这方面的感觉,可以点击这里下载测试所需的可变字体。
如果你使用的是线上托管的可变字体(比如Google Fonts),想了解对应的相关信息时,可以使用Firefox浏览器来进行了解。比如前面示例中用到的Amstelvar VF
字体。在查看页面元素时,选中使用了Amstelvar VF
的元素,并选择浏览器“字体”选项卡,就可以看到可变字体的相关信息:
你可以在“字体”面板中调整你想调整的信息,在调整的同时,可以在浏览器中直接看到相应的效果,如果你选择更改选项卡,您可以轻松地复制和粘贴更改后的CSS,将其带回到您的代码中。
.text {
font-style: italic;
font-variation-settings: "wght" 501, "wdth" 57.3, "slnt" -9, "ital" 0, "opsz" 23, "MONO" 0, "CASL" 0, "XTRA" 572, "GRAD" -0.47, "XOPQ" 402;
}
整个操作过程如下图所示:
操作是不是很简单,如果你对这个功能感兴趣,还可以观看这方面的视频教程,比如@Jen Simmons录制的Quickly Alter Typography with Firefox Font Editor和Firefox Font Editor 。
Step04:设置可变字体样式
前面的内容已提到多次了,CSS Fonts Module Level 4规范中的font-variation-settings
属性可以用来处理可变字体。
font-weight
:设置可变字体的权重,它的值可以是1~999
的任何数字,该属性对应可变字体的wght
轴,即font-variation-settings: "wght" 200
font-stretch
:设置可变字体的字宽(可以对字体进地拉伸或挤压),其值是个百分比值,其中100%
对于的是normal
关键词,50%
对应的是ultra-condensed
,200%
对应的是ultra-expanded
。除此之外还有extra-condensed
、condensed
、semi-condensed
、semi-expanded
、expanded
和extra-expanded
等关键词。该属性对应的是可变字体中的wdth
轴,即font-variation-settings: "wdth" 50
,注意,在font-variation-settings
中的wdth
轴对应的值是不带百分比单位font-style
:有两种方式,第一种是大家熟悉的方式,就是将字体设置为斜体,即italic
,另一种是倾斜,即oblique
,当font-style
取值为oblique
时,还可以指定字体的倾斜角度,比如oblique 10deg
。该属性对应可变字体中的ital
和slnt
轴font-optical-sizing
:该属性用来设置字体的光学尺寸,其值有auto
和none
。默认情况下,浏览器会将光学尺寸设置为auto
,如果你想将其关闭,可以将其值设置为none
。该属性对应的是可变字体中的opsz
轴,可以在font-variation-settings
中指定opsz
,并且其值是一个数字值
比如下面这个小示例:
:root {
--text-vf-wght: 400;
--text-vf-wdth: 95;
--text-vf-slnt: 9;
--text-vf-ital: 0;
--text-vf-opsz: 80;
}
p {
font-variation-settings:"wght" var(--text-vf-wght), "wdth" var(--text-vf-wdth), "slnt" calc( var(--text-vf-slnt) * -1), "ital" var(--text-vf-ital), "opsz" var(--text-vf-opsz);
}
其对应单个CSS属性:
p {
font-weight: var(--text-vf-wght);
font-stretch: calc(var(--text-vf-wdth) * 1%);
font-style: oblique calc(var(--text-vf-slnt) * 1deg);
font-style: italic;
font-optical-sizing: auto;
}
将整个过程所用的代码整合到一起,就会像下面这样:
@font-face {
font-family: "Amstelvar VF";
src: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/57225/Amstelvar-Roman-VF_copy.woff2")
format("woff2 supports variations"), url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/57225/Amstelvar-Roman-VF_copy.woff2")
format("woff2-variations");
font-display: swap;
font-weight: 100 900;
font-stretch: 75% 125%;
}
:root {
--text-vf-wght: 400;
--text-vf-wdth: 95;
--text-vf-slnt: 9;
--text-vf-ital: 0;
--text-vf-opsz: 80;
}
p {
font-variation-settings:"wght" var(--text-vf-wght), "wdth" var(--text-vf-wdth), "slnt" calc( var(--text-vf-slnt) * -1), "ital" var(--text-vf-ital), "opsz" var(--text-vf-opsz);
}
上面我们看到的是可变字体中已知的注册轴(实际上并不是所有可变字体都默认有所有注册轴),但有些可变字体根据设计者设计的不同,可能会有N
个自定义的注册轴,这些自定义的轴始终以四个大写字母为标记,运用于font-variation-settings
属性中:
@font-face {
font-family:'Decovar Regular24';
src:url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/209981/Decovar-VF.ttf');
}
p {
color: #ff8c00;
font-weight: 800;
font-style: italic;
font-variation-settings: "SSTR" 183, "INLN" 648, "TSHR" 460, "TRSB" 312, "TWRM" 638, "SINL" 557, "TOIL" 333, "TINL" 526, "WORM" 523;
}
效果如下:
Step05:降级处理
可变字体是一种较新技术,虽然在2018年中很多主流浏览器都支持该技术,但如果你的业务还需要支持一些更低版本的浏览器时,就难免需要考虑可变字体的降有处理方案。
一般情况下,如果浏览器不支持可变字体的话,将会采用系统级别的字体,但往往这种方式会对整体排版效果有所影响。如果希望在不支持可变字体的浏览器中使用指定的字体,那么我们可以借助条件CSS中的@supports
属性来做降级处理。
如果用代码的话,可以像下面这样:
body {
font-family: 'Venn', sans-serif;
}
@supports (font-variation-settings: normal) {
body {
font-family: 'Venn VF', sans-serif;
}
}
同样的,你要是在做一个响应式Web应用,那么在不同的断点中可以指定不同的注册轴值,这样排版效果会更完善一些:
h1 {
font-size: 1.8rem;
line-height: 1.1;
font-variation-settings: "wdth" 75;
}
p {
font-size: 1.1rem;
line-height: 1.5;
font-variation-settings: "wdth" 88;
}
@media screen and (min-width: 460px) and (max-width: 699px) {
h1 {
font-variation-settings: "wdth" 85;
}
p {
line-height: 1.6;
font-variation-settings: "wdth" 95;
}
}
Step06:给可变字体添加动画效果
通过CSS的transition
和animation
也可以给可变字体添加动画效果。比如,在不同的状态下改变font-variation-settings
的值,就可以让可变字体动起来,比如下面这个示例,在鼠标悬浮状态下(:hover
)改变font-variation-settings
值:
p {
font-weight: 800;
font-style: italic;
font-variation-settings: "SSTR" 183, "INLN" 648, "TSHR" 460, "TRSB" 312, "TWRM" 638, "SINL" 557, "TOIL" 333, "TINL" 526, "WORM" 523;
transition: font-variation-settings .28s ease;
&:hover {
font-weight: 400;
font-style: normal;
font-variation-settings: "SSTR" 283, "INLN" 248, "TSHR" 160, "TRSB" 112, "TWRM" 338, "SINL" 257, "TOIL" 133, "TINL" 426, "WORM" 223;
}
}
除此之外,在@keyframes
不同的帧中指定不同的font-variation-settings
的值,然后在animation
中引入@keyframes
中指定的动画,也可以实现可变字体动画效果,比如下面这个示例:
@font-face {
font-family:'Decovar Regular24';
src:url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/209981/Decovar-VF.ttf');
}
h1 {
margin: 0;
font-size: 20vw;
font-family: "Decovar Regular24";
color: white;
font-variation-settings: 'SSTR' 1000;
animation: loadin 4s infinite linear;
}
@keyframes loadin {
0% {
font-variation-settings: 'SSTR' 1000;
}
50% {
font-variation-settings: 'SSTR' 0;
}
}
我们可以进一步利用这些概念,将可变字体和JavaScript的一些API结合在一起实现一些不同的交互效果。重要的是,无论你是使用设备的朝向、光线传感器、视窗大小、滚动事件还是鼠标移动,其中基本的JavaScript是不会改变的。
比如下面这个示例,使用鼠标移动来改变可变字体相关的值,因而产生具有弹性的效果:
再来看另外一个示例,将可变字体和JavaScript中的Audio API结合在一起所产生的效果:
有关于这方面更详细的介绍,还可以阅读:
Step07: 性能优化
一般来说,可变字体可以提高性能,因为你只需要使用一个字体文件。静态字体需要在站点上为不同的变体加载不同的字体文件,而可变字体本质上是动态的。换句话说,它们在一个文件中包含了所有的可能,这意味着只有一个HTTP
请求,而不是多个。此外,你只需要使用一个@font-face
规则,这将生成更小的CSS文件。
另一方面,可变字体文件非常大,因为它包含了所有的变化。例如Roboto
可变字体的TTTF
格式为3.36MB
,而静态的Roboto
字体变体的TTF
格式文件大约为165~175kb
。即使我们需要使用所有的变体(大约有12
种变体),总共也只有约2MB
。
最终,可变字体的性能权衡取决于这两个指标,即HTTP
请求的数量和字体文件的总大小。
除此之外,在Web中使用可变字体,我们还可以采用一些性能优化的技术来提高可变字体给Web性能造成的影响。比如使用DNS Prefetching
和Preconnect
:
<link href="https://fonts.googleapis.com/css?family=Roboto:400,400i,700" rel="stylesheet">
也可以使用CSS的font-display: swap
对@font-face
进行声明,告诉浏览器显示回退字体,直到可变字体可用为止:
@font-face {
font-family: 'Roboto';
src: local('Roboto Thin Italic'),
url(https://fonts.gstatic.com/s/roboto/v19/KFOiCnqEu92Fr1Mu51QrEz0dL-vwnYh2eg.woff2)
format('woff2');
font-display: swap;
}
开发者可以将 <link rel="preload">
与 font-display
配合使用,以很好地控制字体加载与渲染,而不会增加很多开销。 但是,如果您需要进一步自定义,而且愿意承担运行 JavaScript 所引入的开销,还有一个选项可供选择。
Font Loading API 提供一种脚本编程接口来定义和操纵 CSS 字体,追踪其下载进度,以及替换其默认延迟下载行为。 例如,如果您确定需要特定字体变体,您可以对其进行定义并指示浏览器立即提取字体资源:
var font = new FontFace("Awesome Font", "url(/fonts/awesome.woff2)", {
style: 'normal', unicodeRange:'U+000-5FF', weight:'400'
});
font.load().then(function() {
document.fonts.add(font);
document.body.style.fontFamily = "Awesome Font, serif";
var content = document.getElementById("content");
content.style.visibility = "visible";
});
另外就是,字体资源通常是不会频繁更新的静态资源。 因此,它们非常适合较长的 max-age
到期,即确保您为所有字体资源同时指定了条件 ETag
标头和最佳 Cache-Control
策略。
如果您的网页应用使用 Service Worker,则使用缓存优先策略提供字体资源适合于大部分用例。
不应使用 localStorage
或 IndexedDB
来存储字体;这两者自身都有一些性能问题。 浏览器的 HTTP
缓存可以提供最佳且最可靠的机制来向浏览器提供字体资源。
如果你对@font-face
引用自定义字体(可变字体)性能优化方面感兴趣的话,还可以阅读:
- Variable fonts: Is the performance trade-off worth it?
- The Performance Benefits of Variable Fonts.
- 网页字体优化
- Improving web font performance: a case study
@font-face
and performance- Optimizing Google Fonts Performance
- Performance and Usage Implications of Custom Fonts
使用可变字体的陷阱
可变字体对于Web的排版来说更丰富了,但是随着新技术的发展,需要注意的地方也就多了。
- 可选性太多:可变字体提供了很多以最微小的方式来改变某事的可能性,但这样选择就变得更加困难了。
- 需要更多的排版知识:可变字体有很多东西可供选择,这意味着你必须清楚自己想要什么,以及为什么想要。它也更易于搞砸,更容易在你的设计中出现不一致。这也涉及到评估什么是合适的字体。当然,你可以像以前一样只使用全名实例,而忽略其他选项。唯一改变的是你只需要加载的一个字体文件。
- 并不总是有性能上的提高:如果你只需要一种字体样式,那么可变字体文件将会更大。大多数情况下,当你需要三到四种不同的字体权重或字宽时,你将开始节省文件大小。
小结
可变字体是有意义的,而且易于丰富Web排版。也更易于还原设计师期望的效果,另外就是,到目前为止,很多主流浏览器已经支持了可变字体技术,但对于可变字体的使用还是有一定的障碍性,比如文章中提到的性能(可变字体类型,字体文件越大)以及可变字体的设计(并不是人人都能设计出想要的字体)。在这篇文章中,主要和大家探讨了有关于可变字体相关技术以及如何在Web中的使用。最后希望该文能帮助你对可变字体有一定的了解。如果你对这方面技术感兴趣的话,还可以阅读:
- An Introduction to Variable Fonts
- How to start with variable fonts on the web
- Implementing a variable font with fallback web fonts
- Variable Fonts: What web authors need to know
- Variable Fonts
- A Variable Fonts Primer
- 25 CSS Variable Fonts Tutorials, Tools & Demos
- Dynamic Typographic Systems, Modern CSS & Variable Fonts