计算机科学中最困难的问题:居中对齐

原文信息: 查看原文查看原文

Hardest Problem in Computer Science: Centering Things

- Niki

这是我的说法:作为一个文明,我们忘记了如何居中对齐。

我的意思是,我们知道如何做到这一点。这从未如此简单过:

display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */

(不要问为什么你需要记住四个词而不是只记住水平/垂直,这仍然比以前好

或者,如果你想要的话,你也可以使用网格:

display: grid;
justify-items: center; /* 水平居中 */
align-items: center; /* 垂直居中 */

(也不要问为什么 justify-content 变成了 justify-items

如果你今天感觉像上学一样,我们可以从第一原理推导出它:

嘿,即使 ChatGPT 也知道如何居中对齐:

好吧,也许不是马上,但最终它会成功的。

我想说的是:每个人都知道如何居中对齐。这是微不足道的。而且,如果你迷失了,知识就在那里。

然而,当我们看实际应用时,我们发现这些方法并没有被使用。我们看到这样的情况:

或者这样的情况:

甚至是这样的情况:

因此,在知识和应用之间显然出现了某种失误。

理论上,理论与实践之间没有区别。不幸的是,我们生活在实践中。

那么,到底发生了什么?让我们找出来。

字体

字体是最大的问题之一。你可以看到到处都是对齐不良的文本。让我举个例子。

苹果做不到:

微软也做不到:

GitHub 也做不到:

Valve 也做不到:

Slack 也做不到:

Telegram 也做不到:

Google Maps 也做不到:

老实说,我甚至可以提供无数例子的对齐不良的按钮,甚至不需要去找:

我想你明白了。无论大小、本地还是网络,无一幸免于文本居中问题。

行高

如果字体度量不足,那么通往完美居中的下一个问题就是行高。

行高是……复杂的。了解它的经典文章是 Vincent De Oliveira 的 CSS 深入:字体度量、行高和垂直对齐

这是实际应用中的样子。Slack:

Notion:

Airbnb:

YouTube:

将两个不同容器中的内容对齐几乎是不可能的:

虽然很多人已经尝试过:

但很少有人成功:

CSS 可能会妨碍你(不同的控件具有不同的默认值,你必须在开始尝试对齐之前先撤销这些值):

这里没有简单的解决方案,只能深入研究规范。

图标

图标就像是放在文本行中的小矩形。因此,所有由文本和行高引起的问题也适用于这里。将图标与文本对齐是一个众所周知的难题。

Atom:

前称为 Twitter 的平台:

iOS:

Mozilla:

YouTube:

有时图标胜过文本:

有时文本胜过图标:

有时两者都输:

一些图标只是普通的旧 HTML 表单控件:

有些是样式化的:

感谢 @bee 提供图片

有时人们会想方设法实现完美对齐:

但总体来说,这是一个相当无望的游戏:

问题在于,CSS 也没有帮助我们。vertical-align 属性有 13 种可能的值,但没有一种能够对图标进行有意义的对齐:

text-align: middle 是最接近的,但它是按 x-高度对齐的,而不是大写字母高度,这看起来仍然不平衡:

这正是为什么人们如此喜欢 web 编程的原因。总是有挑战。

图标字体

对齐矩形相对容易。对齐文本很难。图标是矩形。那么,如果我们将图标放入字体文件中会发生什么呢?

现在我们无法对齐任何东西了:

我们也无法设置图标大小!在上面的例子中,所有图标都设置为相同的字体大小和行高。正如你所见,它们的大小都不同,有不同的内边距,并且没有一个正确对齐。

尽管存在许多缺点几乎没有优点,但公司们还是急于在各处添加图标字体。结果是这样的:

macOS 10.14 → macOS 10.15

注意运算符不再垂直对齐,并且也模糊了。这都是因为切换到图标字体造成的。

苹果对图标字体如此执着,甚至毁掉了 QuickTime 的录制按钮:

看看这个:

是的,它实际上就是这个样子。就像计算器一样。

但他们远非唯一一个。一个:

两个:

三个:

四个:

五个:

六个:

七个:

与文本对齐一样,对齐不良的图标是无穷无尽的。

技能问题

不仅仅是程序员不能做好居中对齐。设计师也一样:

当前版本 / 我的修改

图标的问题在于,有时你必须考虑它们的形状,才能让事情看起来好看:

不好的对齐 / 好的对齐

三角形显然很棘手:

有时它离左边太远了:

有时它离右边太远了:

它甚至可能太高了(行高再次出现):

水平居中

您可能认为只有垂直居中是困难的。不只是垂直的!水平也可能很难:

我认为这些都没有深层次的原因,除了人们就是粗心:

来吧!

这可能是一个故意的决定吗?

我不知道。图标也可能受到影响:

文本也可能受到影响:

可以做什么:设计师

那么,问题到底在哪里?

一切都始于字体。现在,文本块的边界框看起来是这样的:

问题是,它也可能是这样的:

或这样的:

现在,如果您尝试通过居中其边界框来居中文本,会发生什么?

文本将偏移!即使矩形完全居中。

但即使字体 可以 有其度量不平衡,也不意味着它会。在现实中会发生什么?

事实上,大多数 流行字体的度量稍有不足。许多字体 明显 不足:

百分比是大写字母高度

10% 不是一个小数字。对于字体大小为 13 的字体来说,这是一个完整的像素!如果你有 2× 缩放,那就是两个像素!很容易注意到。

基本上,Segoe UI 是 GitHub 在 Windows 上看起来像这样的原因:

解决方案很简单:制作紧凑的边界框,居中将变得微不足道:

如果您使用 Figma,它已经可以做到这一点(尽管这不是默认设置):

可以做什么:字体设计师

如果您是字体设计师,请通过设置您的度量值来使所有人的生活更轻松,使 ascender − cap-height = descender

或者是视觉上相同的想法:

重要!您不必 实际上 将您的上扬和下扬延伸到这些边界之间。正如您在图片中所看到的,例如,我的上升空间被低估了。只需使数字匹配即可。

对于网页和本地应用程序都是如此,为避免头痛,请选择已遵循此规则的字体。SF Pro Text、Inter 和 Martian Mono 似乎已经这样做了,所以它们将毫不费力地居中对齐,无需额外努力。

有关更多信息,请参阅 字号是无用的;让我们修复它

可以做什么:web 开发者

从开发者的角度来看,情况会有点棘手。

首先要明白,您需要知道将要使用的字体。不幸的是,如果您计划替换字体,则此方法不起作用。

我们将使用 IBM Plex Sans,这是此页面上使用的字体。IBM Plex Sans 具有以下度量:

当您设置 font-size 时,您设置的是 UPM(这也将等于 1em)。但是,文本块占用的实际空间是上扬和下扬之间的空间。

通过几个简单的计算,我们得到额外的 padding-bottom: 0.052em 应该就可以了:

应该是这样的:

或者在实际的 CSS 中(选择文本以查看默认文本边界框):

您可以从opentype.js.org/font-inspector.html获取您的字体所需的字体度量(上升高度、下降高度、小写字母高度)。

现在我们已经搞清楚了,对齐图标也不是那么困难。您设置vertical-align: baseline,然后将它们向下移动(图标高度 - 小写字母高度) / 2

不幸的是,这需要您了解字体度量和图标尺寸。但是,至少它起作用:

再次选择上面的文本,看看浏览器的边界框与正确位置有多大的差异。

可以做的事情:图标字体

停 止 使用 字体。

用普通图像格式。您知道那个带有尺寸的格式吗?宽度和高度?

在这里,我为您绘制了一个图表,以帮助您做出决定:

看看苹果是多么努力地将复选标记放在矩形内,然后将矩形放在文本标签旁边:

他们仍然失败了!

没有比将两个矩形对齐更容易的事情。没有比试图对齐周围有任意量空白的文本更困难的事情。

这是一个无法赢得的游戏。

可以做的事情:光学补偿

我们,开发人员,只能在数学上对齐完美的矩形。因此,对于任何需要手动补偿的内容,请将其包裹在足够大的矩形中,并在内部视觉上平衡您的图标:

可以做的事情:每个人

请注意。请关心。糟糕的居中对齐可能会破坏原本体面的用户界面:

但是正确对齐的文本可以让您的用户界面奏响:

即使困难。即使工具使它不方便。即使您必须寻找解决方案。我相信,我们共同努力,我们可以找到一种方法,将一个矩形放入另一个矩形而不会搞砸。

我,个人而言,希望生活在一个拥有美丽且平衡的用户界面的世界中。我相信您也是。

最终,这一切都是值得的。

分享于 2024-05-15

访问量 57

预览图片