Thoughts, stories and ideas.

原文:Getting to the bottom of line height in Figma

在 Figma,我们努力在几百年来设计传统和现代实践之间找到平衡。今天我们取得了新的成就:我们调整了文字的处理方式。Figma 现在会在文字的上方和下方显示间距,并且用一种更现代的方式处理行高(line height)。这完全是可选的:你的既有文件不会发生任何变动,你可以选择是否按照新模式处理文字。

这些修改看似简单。为了给用户找到最合适的方案,我们探索了美丽而又复杂的文字和垂直对齐的世界,研究自古腾堡以来如何排列文字,以及现在的电脑——开始时图形界面,接着是 web——如何使问题更加复杂。

这个历史包袱,以及Figma被各种方式使用的事实,使得提出一种理想的解决办法很具有挑战性。我们做了很多研究和测试,很激动能展示我们的成果。

如果你想直接进入主题,你可以直接跳到该部分或阅读我们的支持文档。或者,你也可以跟我一起进入字体的过去和现在。我们会和 CSS 的作者聊天,为 OS/2 默哀,希望能更好的理解如今 Figma 做出的改变。

早期的排版

在金属字模的年代事情要简单许多。有两个基本角色:字体设计师和排字工,他们的工作受物理条件限制。

到了 19 世纪一直如此,字体行业已经弄清了大部分的准则。一个字体的生命始于纸上,字体设计师花费数周乃至数月画出文字的草稿。当完成设计后,绘制的字体(typeface)将变成字模(font):真实的铅块。

译注:typeface 和 font 容易弄混,但实际上它俩并不一样。这两个词起源于印刷术,typeface 指字体的设计,是抽象的;font 是一个特定的字体和字号构成的铅字,是具象的。现在数字时代一般称一套字体为 typeface,其中的某个字重为该 typeface 的 font 。按照文章意思,这里的 font 指实体的铅字块。

你要为每个字母买若干个铅块。你也需要买不同大小的铅块。但是字号(font size)并不是由字母决定,而是由铅块的高度决定,这个高度单位就是点(point),一点等于 1/72 英寸,或者 0.4 毫米。铅块的高度固定,但是在铅块里,字体设计师可以任意设计:相同字号(铅块高度)里的字可大可小,他们的基线(baseline)可高可低。

不同字体的行高表现不同
4 种相同字号的不同字体,都是 16 号。注意有的字体占据更大的空间,基线位置也各不相同。

当字体设计完成铅字完工,雇佣这些设计师的铸造厂就会把字模卖给印刷厂。印刷厂雇佣的排字工将铅字排列组成单词,然后是句子,段落,最后到页面。

铅字模

排字工可以很快的把字模排成一行,并将每行字模挤在一起。通常他们会在两行文字之间插入窄金属条,让文字能呼吸,使读者的视线从行尾跳到行首时眼睛更舒服。

增加行距
增加行距

这个空白条是用铅(lead)做的,所以这个间隙就被叫做行距(leading)。下图是个 16 号(pt)字增加了 4 点行距的效果,整行文字的行高(line height)是 20 点。

增加了leading的文字

找到最佳的行距是字体的艺术。根据字号和行宽结果会不同。即便使用相同的字号和行距也可能导致一个字体显得紧凑,另一个显得漂浮。

很多种不同字体
左边,一家铸造厂夸耀他们的基线始终保持统一。右边,一个新的想法:字体大小与数字对应,而不是随意的命名。

这是一个相对简单的系统,具有明确的角色和规则。字体来自铸造厂,作为单独的不可修改的块,行距只能增加,不能减少。当然你也可以设置一个非同寻常的行高,但这种情况并不常见。(这种字体会被骂为“混账字体”)。你的工作就是把字模按你心中的内容按顺序排列好。

引入像素,引入麻烦

然而计算机毁了一切。当我们从纸和铅字转变为屏幕和软件,字体排印继承了所有计算机所能提供的,包括漏洞、不兼容以及更新。

字体不再是固体金属块;反而它们作为数据打包进文件。字体设计师需要将字体转换成不同格式,以满足早期图形界面平台:Windows、Macintosh 和已经被遗忘的 OS/2。此外,平台的字体渲染可能会有缺陷,字体商需要对此进行调整。

当然并不是所有方面都很糟糕。电脑给了字体设计师前所未有的自由。像素很少受实体铅字规则的限制,可以重叠,也可以溢出边界。作为排字工,你可以加任意行距而不需要实体的金属条。或者你也可以去掉行距,如果你愿意的话。

任意修改行距
在屏幕中的文字加入和减去行距

在现实世界中,一个铅块需要有一个最小尺寸,因此行距只能增加。但在数字世界中,一个字体的默认行高可以设置为任意数字,一般会比字号大一点。(不是固定值)

被设置成不同默认行高的四种字体
4 个数字字体,都是 16 点的字号以及 100% 的行高

但是适应新发现的自由需要一些时间。像 Photoshop 和 QuarkXPress 这样的早期图形程序仍然用于设计印刷品,所以你可以完全控制字体,精确地测量和定位所有内容。因此这些程序仍然遵循与印刷相同的规则。例如下图的 Photoshop,可以设置 16 点的字体并增加 4 点的行距。

早期版本的 Photoshop 和 QuarkXPress 的字体设置窗口。
早期版本的 Photoshop 和 QuarkXPress 的字体设置窗口。

其他程序略有不同。 有时他们会问你行高(在这种情况下是 20 点),而不是行距。 或者,您可以说“我想要一个 100% 的行高”,这意味着字体的默认行高由字体设计者指定,可以是 16 点,20 点或任何其他值。

任意修改行距
软件中的行距

事情逐渐发展。随着电脑屏幕的扩张,屏幕变成了目的地而不是中转站。更多设计针对屏幕,并产生了不同的需求。特别是在用户界面设计中,文本与 Icon 垂直对齐变得更加重要,而这在印刷品中不那么重要。

与此同时,一些老的传统消失。行高开始用像素(pixel)而不是点来表示。随着铅字(lead)的消失,“行距 leading”逐渐被“行间距 line spacing”代替。

所有互相竞争的字体标准也逐渐融合子一起。业界推出了OpenType,一个统一的字体标准可以用于各处。但在文件内部有点奇怪,有三组不同的数值,不同的平台只会选择其中一组。

三组略有不同的字体效果。

Web 中的行

1989 年 web 诞生了,挑战更加复杂。

早期网络的构建者们做了两个改变行高本质的决定。首先他们为文字上下都分配了额外的空间——如果你还记得刚才的内容,行距在文字下方——他们称之为 half-leading

任意修改行距
印刷(左)和 web(右)对行距的不同处理

我联系了 CSS 的作者,以了解改变背后的理由。他们解释道,虽然网络样式表的早期提案的确和印刷领域相似,但他们有足够的理由采用 half-leading。即 web 的文字区块(text box)需要负担更多。

在印刷界和早期程序中,文字区块只需要将文字包裹在其中。Web 需要它做得更多。“我知道 half-leading 不是传统的印刷概念”,在 1995–1996 年负责 CSS1 的伯特·博斯(Bert Bos)说道:“但是如果仅仅在下方增加行距会导致使用背景或边框的时候出现问题。”

如果行距只出现在文字区块底部,会导致底部显得很重并需要额外工作才使效果好一点。Half-leading 提供了解决办法。

CSS 的另一个改变是什么?100% 的行高(line height)等于 100% 的字号(font size)。在此之前,字体设计师可能会给 16 像素字号的字体一个默认的 20 像素的行高。但是在 web,16-pixel 字号的字体的 100% 行高就是 16 像素,无论字体设计师当初如何定义。

这个策略的原因很简单:要知道一个字体的默认行高需要先加载这个字体,在早期的互联网会很慢。使行高等于字号则可以很快计算完成。“我们希望在没有加载字体的时候就尽可能多的进行计算”, CSS 联合作者哈科·尼姆·李(Håkon Wium Lie)提到。行高不再取决于内部的字体属性,好在字体不需要适应什么物理边界,所以这不算什么问题。

设计稿和开发实现的些许不同
对比不同的字体在 16 号字和 100% 的行高下的表现。

所以,相同的 16 号字这时候还是 16 号,但是 20 像素的行高就得设为 125% 或 1.25,因为16×1.25=20

任意修改行距
行距在 CSS 中可以有三种表现方式

Web 也从排字工手中夺走了一些权力。印刷世界的规则是绝对的,现在成了建议性质。要想让文字恰好在你期望的位置变得更难——但不建议这么做。毕竟浏览器用于各种不同的电脑上,有着不同的屏幕和字体。

浏览器,像以前的平台,现在需要负责字体的渲染和排版。但你可以想见,每个浏览器有自己的特性和缺陷。每个处理方式都不一样:如何对齐,如何处理像素点,如何解释 CSS 的各种咒语。

Web 设计的历史可以看成想要精准控制权的设计师和阻止他们的 web 之间的拉锯战。这种拉锯的一个意外结果就是行高。早期的 web 不允许垂直居中——如何让文字和 icon 垂直对齐一直是个很蛋疼的事——但是利用行高属性 web 提供了一个在界面设计领域很常用的一个方法。

设计稿和开发实现的些许不同
左:垂直对齐;右:通过使行高等于 icon 高度实现垂直对齐。

短短的几十年里, 蒂姆·伯纳斯-李(Tim Berners-Lee)的发明超越了任何人的想象,但 web 并没有接管整个世界。桌面应用变成了 iOS 和 Android 的应用,在系统的底层,它们继续沿用印刷传统。

现在所有人的电脑上,有应用也有网站,两者对字体的看法略有不同。很难说哪一种更优越,但是可以肯定的是它们不兼容。

年轻的数字排版也迅速积累了历史包袱。关于键盘有个笑话:为什么键位是这样排列的?因为之前就是这样排列的。字体排印也是如此。

结果是什么?字体的表现不再是唯一的。

Figma 的改变

这种关于行高的历史包袱,不是我们想让 Figma 继承的。但我们没有选择。除了上文提到的各项挑战,Figma 也有自己的难点:

  • 人们在不同的平台使用 Figma
  • 人们使用 Figma 设计不同平台的产品
  • 人们会同时进行操作(多用户)
  • Figma 现有的庞大生态需要理解和尊重

字体的表现不再唯一,但 Figma 思考字体时需要统一。我们不能在不同平台采用不同的渲染,这样在协作的时候会产生麻烦。我们希望支持你在 Chromebook 的浏览器上设计 iOS 应用,或者在 Mac 上设计 Android 应用,但我们不希望设置一套切换规则来让 Figma 字体像某个平台。我们需要创建一个方便,功能强大的用户界面,但也要意识到 Figma 的工作最终会在 CSS 或原生代码中体现。

Alt Text!
为了实现这个目标,Figma 需要接管所有工作,解释字体文件,制定以前浏览器所做的决策,减少设计抉择的空间

Figma 最初完全采用了印刷的规则:行间距增加在下方并且 100% 意思是字体的默认行高。但是很明显,人们逐渐不再以这种方式使用字体。相反,他们期望字体表现和 web 一致,因为我们的做法导致设计和开发交接时出现偏差,甚至是对于设计师来说也是如此。

我们经常听到抱怨说 Figma 的文字很令人困惑,所以我们更谨慎的审视。我们观察发现人们使用 Figma 为所有平台设计界面和视觉。我们做了一个小工具帮助我们理解不同平台的字体表现。我们进入历史了解行高和字体排印的演变。

任意修改行距
我们做了一个工具研究不同平台下行高的设置和效果。你可以在这里体验。

我们也遇到了大量棘手的问题,希望你们不会碰到。

任意修改行距
我们研究行高的主文件

经过研究和讨论,我们确定了一系列关于在 Figma 中如何处理行高的变化。我们希望这个解决方案能满足你的更多需求,同时不会给少见需求带来麻烦。

  1. 行高的分布

在文本框内部,Figma 将会对行高采用与 web 一样的做法。

leading在上下两侧添加,而不是只在下方
  1. 后续行的处理

后续行的行距会加在其上,CSS 则是加在上下两侧,也与 Figma 加在下方的之前处理方法不同。我们相信行距在一个地方会更容易控制。

  1. 百分比字号

行高的 100% 如今意味着“100% 的字号”而不是“100% 的默认行高”。这应该会让计算更容易。

文本框也会有自动行高。当你切换字体的时候,我们会调整行到字体的默认行高。这会轻易看出不同字体的区别。如果你将行高设置为固定像素或百分比,我们尊重你的选择。

  1. 行高的像素单位

说到像素......从现在开始,当你说“我希望我的行高为20像素”时,我们就会更坚决的尊重——即使 web 不会这样(CSS 中的行高是最小行高)。 我们看到人们使用特定的行高值来对齐元素,我们希望尊重这一点。

  1. 🤗❤️✏️

我们也发现用户——包括我们自己——插入 emoji 破坏文本韵律时会烦恼。现在如果你插入 emoji,我们将不会改变文本框块的大小。

关于 emoji 和文字应该写本书
关于 emoji 和文字应该写本书
  1. 字体属性

之前我们根据一种方法解释字体。这会导致有些字体比预期的要偏上。如今已经修复。

  1. 字间距(letter spacing)

如果最后一个字母有额外的字间距,Figma 现在会忽略它。这与 web 不同,但会好的居中文本。

没有绝对正确的查看字体的方法,但我们相信这是一种比以前更好的方式。这应该会比以前解决更多实际问题,并且没有让任何事情变更难。在代码面板,我们现在会输出更多信息帮助设计和开发的交接。

有些事情我们无法解决。比如字体设计师可以让字在文字区块内非常高,我们应该尊重他们的做法。更复杂的是,甚至很难定义什么是垂直居中。字体就是那种看着可能[效果很好但数据并不总是正确](Typography is impossible – Medium Engineering的世界。下图的例子都可以称之为垂直居中,但这取决于设计师而不是 Figma。

如图中例子所示,垂直居中可能意味着不同的含义

但总的来说,我们希望 Figma 比以前能更快的做对的事,并允许你作为设计师更快地做出决策(并且比工程师更好地理解这些决策)。 我不认为人们应该了解我刚刚列出的七个细微差别。 目标仅仅是让 Figma 的字体渲染效果更好。

我们也希望尊重您在 Figma 中已经制作的设计。 如果您创建一个新文本框,您将获得上述文本渲染的更新,但我们不会自动升级您之前的任何文本框,因为这可能会导致上下移动。

您可以按照自己的步调更新以前的文本框(逐个更新,或选择画布上的所有图层一起进行),任何更改都是可逆的。

自行选择是否应用新的模式

最终的结果

我最近加入 Figma 设计团队负责排版,这就是我开始的一个项目。我从排字中学到了很多,我也相信我只是掌握了一点皮毛。

在城市设计中有一句谚语:“如果你能理解一个城市,那个城市已经死了。”人们如何组织他们的建筑以及生活以各种不可预测的方式发展。很容易看出它既凌乱又烦人,但是人们也可以看到它美丽而且非常人性的一面。我经常以这种方式看待排版,作为一种无限复杂,富有历史和意义的东西。我对此感到敬畏,感觉是一种成为那段旅程的一部分的荣幸。