Skip to content
0

字体度量

字体度量是指字体设计中用于测量和描述字符形状、尺寸、位置以及字符之间空间关系的参数和标准

字体度量帮助计算机确认行之间的默认间距,sub 和 super 应该多高或者多低,以及如何将两个不同大小的文本并排对齐

这些度量的数据连同其他的元数据一起保存在字体文件的 Font Tables 中,你可以在这个网站上传一个字体,并看到关于它的 Font Tables

对于开发者,哪怕是设计师来说,这些知识过于精细,以至于我们经常忽略它。但是我们通过了解字体度量,理解开发中我们碰到的许多问题

结构

下面是我画的一副示意图,展示了 jEh 三个字母为例子的,各个子元素之间的距离名称

undefined
undefined

Baseline

最有用的结构就是 Baseline 了,中文名叫做基线,这很像我们以前练习写英文的时候,四线三行中的第三根线

一般来说,同一行的文字,哪怕颜色不一致(有强调),文字都是需要在同一基线上的,整齐的排版使得我们能够很轻松地阅读一段文字

undefined
undefined

类似的,从上到下,其他三根线的名字是:顶线(TopLine)、中线(MiddleLine)、底线(BottomLine)

基线还有助于创建垂直的规律,这可以使读者更容易从一行跳到另一行,从一个段落跳到另一个段落,从一个章节跳到另一个章节

Ascender/Descender

在众多参数当中,决定字体渲染高度的两个主要参数是 ascender 和 descender,中文分别称为上升部和下降部

我们简单地可以理解为:四线格中第一线到第三线之间理解为上升部,第三线到第四线之间理解为下降部(需要注意的是这里只是方便理解,实际的字体设计中一个字母并不会像四线格写法一样完全填满上升部或下降部。)

减少 CLS

在前端领域,CLS 代表 Cumulative Layout Shift(累积布局位移)。CLS 衡量的是页面加载过程中元素布局发生不稳定的程度

我们知道,字体通常是网页中加载较慢的资源,尤其是全量的字体包。那么当字体的加载速度比网页慢的时候,浏览器会使用备用字体进行渲染(使用过第三方字体经验很容易观察到这个现象)文本,直到字体加载

当字体切换到新字体的时候,会出现文本偏移和闪烁等问题,这些文本的重绘会降低 CLS 分数,进而影响用户的体验以及 Google Search page ranking 等(字体的切换还可能导致布局的重大改变,进而获得更低的 CLS 分数)

字体的优化有许多种方式,例如加快资源的速度,以及在必要的时候,不展示新字体:

<!-- 1: links at top of head -->
<head>
<meta charset="utf-8">
<!-- 2: preconnect -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<!-- 3: use font-display -->
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=optional" rel="stylesheet">

fallback

为什么会产生布局偏移?

因为字体加载一般具有延迟,那么就会先显示 fallback 字体,而 fallback 字体一般与你的字体的基础度量单位有差距,这样就会导致浏览器重新计算某些标签的大小,从而导致布局偏移。

怎么减少布局偏移?

浏览器提供了 ascent-overridedescent-overrideline-gap-override 来操作一个 font-family 的基础度量。 我们可以创建一个 fallback 字体,链接到本地的字体上,然后调整 override 相关属性来将两种字体的显示大小尽量保持一致。

unjs 下有一个仓库 unjs/fontaine,可以为字体生成 fallback,这个措施就是为了减少页面的 CLS

@font-face {
font-family: 'Roboto';
font-display: swap;
src: url('/fonts/Roboto.woff2') format('woff2'), url('/fonts/Roboto.woff')
format('woff');
font-weight: 700;
}
:root {
font-family: 'Roboto';
/* This becomes */
font-family: 'Roboto', 'Roboto override';
}

上面的 Roboto override 引用的 src 都是本地的资源,所以无需网络加载,会被浏览器当作默认字体的第一选择

通过给定 ascent-overridedescent-override 等属性,使得 Roboto override 字体更加接近 Roboto 字体,这样的话,虽然无法 100% 确保前后无变化,也能一定程度上减少字体变化带来的布局影响

Link: reduce-font-loading-impact-css-descriptors

Link2:https://chinese-font.netlify.app/post/performace_turbo/

Released under the MIT License.