#78 font-size-adjust 简谈

网页字体微调

Design Scenes 第 78 期封面,采用了不同字体gou'che

旧闻一则:Safari 17.0 支持 font-size-adjust 更多特性,可以直接使用 from-font 值和双值语法,包括 CJK 文字 ic-height 值。这个 CSS 特性解决的是网页字体 fallback 场景下不同字体的大小对齐问题,尽量让保持字体大小一致,增加可读性。

哆啦A梦中大雄表情包:特意把大家喊出来,就是为了这点事呀。

举个例子

调整前的一句英文:This is a static template, there is no bundler or bundling involved! 其中 static template 字体不同,且看起来较小

为了效果直接,我挑了个极端的对比。上图中衬线字体为 Google Sans,中间特殊字体为 Baskerville,默认都是 16px 字号,「调整前」Baskerville 视觉上明显小了一些。font-size-adjust 可以单独微调字号,让其按照 x-height 或其他标准对齐。

font-size: 16px;
font-size-adjust: 0.5;
是否使用 font-size-adjust 的文字对比,其中 static template 看起来和其他字母一样大小
是否使用 font-size-adjust 的文字对比

X-height 对一款西文字体的风格体现很重要,高于均值的 x-height 字体在小字号中更易读,低于均值的 x-height 字体更不落窠臼,而 x-height 过高和过低都会导致难以辨认字形。

在正文排版中,基线对齐是标准,按照相近的 x-height 高度排版便能起到对齐效果。font-size-adjust  默认值便是如此,双值语法即:

font-size-adjust: ex-height 0.5;

0.5 代表待调整字体的 x-height 高度之于 font-family 首选字体的 font-size 比例,在这里也就是,我们想让 Baskerville 的x-height 和 Google Sans 一样,即 16 * 0.5 = 8px 高。

至于0.5 怎么得出来的了——WWDC 23 的 What’s new in CSS 视频中会说,大部分比值都在 0.5 左右徘徊:

x-height / font size ≈ 0.5

所以只要试出一个自己满意的值即可。当然如果想精准一些,也可以自己到软件里手动测量。

Figma 中 Google Sans 和 Baskerville 各度量辅助线对比

如图,为了取整(和在 Figma 里演示)方便,均为 80px 字号的字体,实际量得Google Sans 的 x-height 为41(取整),Baskerville 的 x-height 为 32(取整)。一个比例 0.5 一个比例 0.4,相差甚远。

对 Baskerville 进行 font-size-adjust 时即可设置为 0.5,反之如果对 Google Sans 调整,即可设置为 0.4。

当然上述只是模糊的参考数值。如果懒得计算也没关系,可以直接试试:

font-size-adjust: from-font;

这样会自动调用字体度量(metrics)来计算,比如 Google Sans 的 x-height 度量为 510,em 为 1000,实际比例就是 0.51。像 Baskerville 这样的老 TTF 字体,em 为 2048,x-height 为 819,实际比例就是 0.3999。

其他特性介绍

除了 ex-heightfont-size-adjust 还支持 cap-height, ch-width, ic-width, ic-height 属性,如图。

各属性代表字体的部位,使用 Aa、0 和水作为示例
各属性代表字体的部位,截图自 What’s new in CSS

图很清晰:

  • cap-height 指的是大写高度,使用 H 和 I 等字母比较方便测量,Figma 中给字体开启 vertical trim 也是该高度;
  • ch-width 指的是字体中数字 0 (唯一指定 U+0030)的步进宽度;
  • ic-width ic-height 指的是 CJK 文字中「水」(唯一指定 U+6C34,不是康熙部首 U+2F54)的步进宽度和高度;
💡
关于步进宽度(advance width)和高度(advance height),直接用图解释比较快。详见 freetype 原文
小写字母 g 的字形参数

所以这么一看,上面 WWDC 23 那张图多少有些不太严谨🤭。

中英混排

从实际出发,这次以 Noto Sans SC 和 Google Sans 混排为例,两者组合是 Google 大中华区不得不品尝的设计风味之一。

与西文字体不同的是,中文不能复用其度量标准。虽然都是在观察负空间和阅读轮廓线,但中文更看重字面、重心和中宫,中宫常与西文的 x-height 相比较,但只处于感知层面没有数值描述。不同结构的文字和其他语言组合也需要考究一番。

Noto Sans SC 中既有英文也有中文,网页实际渲染时会按照英文部分渲染基线和其他度量。所以单就 ic-height 来说并非特殊属性。比如下面一个常见的例子:使用数字和中文搭配成 label 文字的组合。

对「10 条回复」的文字大小调整
对「10 条回复」的文字大小调整

未调整情况下,我们会发现「条回复」明显大于数字,特别是顶部高出一头的感觉很明显。分别使用三种特性对中文进行调整,可以看到中文和数字对齐了一些,同时三种调整几乎没有区别。(注意:这里的汉字首选字体均单独设置为 Noto Sans SC)

「10 条回复」文字中数字和汉字的各处度量对比

如上图各度量使用 Figma 基础设置便可大致显现。

  • 首先 Figma 中字体会自带基线显示;
  • 将文本 line height 设置为 auto 即可显示行高轮廓;
  • 将文本 type settings 里切换 vertical trim 即可显示 cap height,或者打出大写字母 M;
  • 打出小写 x,其高度即为 x-height;
  • 这里的 ic-height 可按照升部+降部计算;

从设计角度看,我们可以先逆过来调整不同文本到一定和谐的比例,然后再去统计此时各个度量数值,从而计算出比例。


但是到环境更复杂的正文中,有时调整局部反而破坏了整体连续性。

使用五种方式调整一段文字对比效果

由于中文与英文衔接处不固定,所以难以大幅度改动排版。比如此例中的「使用 AC」处,一直最稳定的默认调整 from-font 翻车,AC 顶部明显比「用」字高出一头,显得整体中文反而较小。

「使用 AC」字样放大对比}

原因大概在于,设置 ic-height 的前提是基线位置不变,汉字的顶部趋近于英文顶部时,下方并不会相应对齐,从而比例不太和谐。所以此时,在默认比例基础上稍微增加一些数值会更好一些。

其他拓展实例

中文不同字体混排

像我们这种市井设计师,可能会碰到一些比较逆天的排版。这时候中文内不同字体也可以使用 font-size-adjust 调整排版。

使用 font-size-adjust 调整两种不同中文字体

上图中,「宇宙洪荒」使用了站酷快乐体,其他文字使用了 Noto Sans SC。可以看到快乐体整体偏小(当然字重也不匹配,这里先忽略)。到 Figma 里看了一下,同样都是 100 号字体时,快乐体字宽 92,字高 100。所以设置 ic-width 为 100 / 92 ≈ 1.087,效果如图所示。

阿拉伯字体实验

某个平行世界的我可能在研究 8 世纪的炼金文籍,但这个世界的我对阿拉伯文一无所知。在 W3C 的文档看到多层基线时我就先撤退了。直接看看效果:

使用阿拉伯文、中文和英文的对比

上图阿拉伯文是我随便在 Google Font 上找到的字体 Ruwudu,直接用 from-font 调整后高度有所改善。但 Ruwudu 并非是正宗使用 alef height、joining line 或 Meem Depth 等度量的阿拉伯文字体,本质上依靠的还是字体内西文字体的度量,所以实际效果待定。

兼容

目前 font-size-adjust 仅 Firefox (3-120)和 Safari (16.4-17.0)支持,Chrome 可在 flags 里开启。而双值语法特性 (Two-value syntax)仅 Firefox (92-120)和 Safari (17.0)支持,Chrome 不可兼容。

上文图例均在 Safari 17.0 实现。

“font-size-adjust” | Can I use... Support tables for HTML5, CSS3, etc

参考

本次成文离不开各方资料参考:

一些常见字体比例小工具:

延伸阅读

如感兴趣读者可以继续延伸阅读:


如果你觉得文章对你有些帮助,可以请我的猫吃罐头 ↓

带有微信赞赏码和文字 A kind and compassionate act is often its own reward. 的横幅图像

订阅 Design Scenes

发布最新文章时,会以邮件通知你
zelda@link.com
订阅