这是用户在 2024-4-18 14:07 为 https://tonsky.me/blog/centering/ 保存的双语快照页面,由 沉浸式翻译 提供双语支持。了解如何保存?

Hardest Problem in Computer Science: Centering Things
计算机科学中最困难的问题:居中对齐

This is my claim: we, as a civilization, forgot how to center things.
这是我的观点:作为一个文明,我们忘记了如何居中对齐。

I mean, we know how to do it. It has never been simpler:
我的意思是,我们知道如何做。这从来没有那么简单过:

display: flex;
justify-content: center; /* Horizontal centering */
align-items: center; /* Vertical centering */

(don’t ask why you need to remember four words instead of just horizontal/vertical, it’s still better than before)
(不要问为什么你需要记住四个单词而不是只记住水平/垂直,这仍然比以前好)

Or you can use grids if you want:
或者你可以使用网格,如果你愿意:

display: grid;
justify-items: center; /* Horizontal centering */
align-items: center; /* Vertical centering */

(also don’t ask why justify-content became justify-items)
(也不要问为什么 justify-content 变成了 justify-items

If you feel like school today, we can deduce it from the first principles:
如果你今天不想上学,我们可以从第一原理推断出来:

Hey, even ChatGPT knows how to center things:
嘿,就连 ChatGPT 也知道如何居中对齐东西:

Okay, maybe not right away, but eventually it gets there.
好吧,也许不是马上,但最终它会到达那里。

What I’m saying is: everybody knows how to center things. It’s trivial. And if you are lost, the knowledge is right there.
我要说的是:每个人都知道如何居中。这是微不足道的。如果你迷失了,知识就在那里。

Yet, when we look at actual applications, we see that these methods are not used. We see this:
然而,当我们看实际应用时,我们发现这些方法并没有被使用。我们看到这个:

or this: 或者这个:

or even this: 或者甚至这个:

So something is clearly getting lost between know-how and applying that knowledge.
因此,显然在知识和应用之间存在一些失落。

In theory, there’s no difference between theory and practice. Unfortunately, we live in practice.
从理论上讲,理论和实践之间没有区别。不幸的是,我们生活在实践中。

So what’s happening? Let’s find out.
发生了什么事?让我们找出来。

Fonts 字体

Fonts are one of the biggest offenders. You can see poorly aligned text everywhere. Let me showcase.
字体是最大的罪犯之一。你可以在各处看到排版不佳的文字。让我展示一下。

Apple can’t do it:
苹果做不到:

Microsoft can’t do it:
微软做不到:

GitHub can’t do it:
GitHub 无法做到:

Valve can’t do it:
Valve 无法做到:

Slack can’t do it:
Slack 无法做到:

Telegram can’t do it:
电报无法做到:

Google Maps can’t do it:
谷歌地图无法做到:

Honestly, I can provide an endless supply of poorly-aligned buttons without even having to look for them:
说实话,我可以提供无穷无尽的排列不整齐的按钮,甚至都不用去找它们:

I think you get the idea. Myriad companies big and small, native or web, and none are safe from text-centering problems.
我认为你明白了。无数的大大小小公司,本地或网络,都无法幸免于文本居中的问题。

Line height 行高

If font metrics are not enough, the next problem on our way to perfect centering is line-height.
如果字体度量不足够,通往完美居中的下一个问题就是行高。

Line height is... complicated. A canonical article to learn about it is Vincent De Oliveira’s Deep dive CSS: font metrics, line-height and vertical-align.
行高是...复杂的。了解它的一个经典文章是 Vincent De Oliveira 的深入了解 CSS:字体度量、行高和垂直对齐。

This is how it looks applied in practice. Slack:
这是实际应用的样子。Slack:

Notion:

Airbnb: 爱彼迎

YouTube: YouTube

Aligning two things in different containers is almost impossible:
在不同容器中对齐两个元素几乎是不可能的

Although many have tried:
尽管许多人尝试过:

Not many have succeeded:
成功的人并不多:

CSS might get in the way (different controls having different defaults which you have to undo before even starting trying to align):
CSS 可能会成为障碍(不同控件具有不同的默认值,您必须在开始尝试对齐之前撤消这些默认值):

No easy solution here, just roll up your sleeves and delve into specifications.
这里没有简单的解决方案,只需卷起袖子,深入规格。

Icons 图标

Icons are like small rectangles put in line with text. Therefore all problems caused by text AND line height apply here. Aligning icons next to text is a notoriously hard task.
图标就像放在文本旁边的小矩形。因此,由文本和行高引起的所有问题都适用于此处。将图标与文本对齐是一个众所周知的困难任务。

Atom: 原子

Platform formerly known as Twitter:
曾被称为 Twitter 的平台

iOS: iOS

Mozilla:

YouTube:

Sometimes icon wins over text:
有时图标胜过文字:

Sometimes text wins over icon:
有时文本胜过图标:

Sometimes both lose: 有时两者都输:

Some icons are just plain old HTML form controls:
有些图标只是普通的旧 HTML 表单控件:

Some are stylized: 一些是风格化的

Thanks @bee for the picture
感谢 @bee 提供图片

Sometimes people will get creative to achieve perfect alignment:
有时人们会发挥创意,以实现完美的对齐:

But overall it’s a pretty hopeless game:
但总的来说,这是一个相当无望的游戏:

The problem is, CSS doesn’t help us either. There are 13 possible values for the vertical-align property, but none would align the icon in a meaningful way:
问题是,CSS 也无济于事。对于 vertical-align 属性,有 13 种可能的值,但没有一种能够以有意义的方式对齐图标:

text-align: middle comes closest, but it aligns by x-height, not cap-height, which still looks unbalanced:
text-align: middle 最接近,但它是按 x-高度对齐的,而不是按大写字母高度,这看起来仍然不平衡:

That’s exactly why people love web programming so much. There’s always a challenge.
这正是人们为什么如此喜爱网络编程的原因。总是充满挑战。

Icon fonts 图标字体

Aligning rectangles is relatively easy. Aligning text is hard. Icons are rectangles. So what if we put icons into a font file?
对齐矩形相对容易。对齐文本很难。图标是矩形。那么,如果我们把图标放入字体文件中会怎样呢?

Now we can’t align anything:
现在我们什么都无法对齐:

Neither can we set icon size! In the example above, all icons were set to the same font size and line height. As you can see, all of them come out different sizes, with different paddings, and none were properly aligned.
我们也无法设置图标大小!在上面的示例中,所有图标都设置为相同的字体大小和行高。正如你所看到的,它们都呈现出不同的大小,有不同的填充,并且没有正确对齐。

Despite many shortcomings and almost no upsides, companies rushed to add icon fonts everywhere. The result is this:
尽管存在许多缺点,几乎没有任何优点,但公司们仍然急于在各处添加图标字体。结果就是这样:

macOS 10.14 → macOS 10.15

Notice how operators are not vertically aligned anymore and are also blurry. All because of switching to icon font.
注意操作符不再垂直对齐,而且也变得模糊不清。这都是因为切换到图标字体造成的。

Apple was so committed to icon fonts they even ruined the QuickTime record button:
苹果公司如此执着于图标字体,甚至连 QuickTime 的录制按钮都被毁了。

Just look at it:
就看看吧:

Yes, it actually looks like this to this day. As does the calculator.
是的,事实上,它看起来就像今天这样。计算器也是如此。

But they are far from being the only ones. One:
但它们远非是唯一的。一:

Two: 二:

Three: 

Four: 

Five: 

Six: 

Seven: 

Same as with text alignment, there’s an endless supply of poorly aligned icons.
与文本对齐一样,对齐不良的图标也是无穷无尽的。

Skill issue 技能问题

Not only programmers fail to center things. Designers do it, too:
不仅程序员会居中失败,设计师也会。

Current version / my fix
当前版本/我的修复

The problem with icons is that sometimes you have to take their shape into account for things to look good:
图标的问题在于有时你必须考虑它们的形状才能使事物看起来好看:

Bad centering / good centering
错误的居中/正确的居中

Triangle is notably tricky:
三角形特别棘手:

Sometimes it is too far to the left:
有时候它太偏左了。

Sometimes it’s too far to the right:
有时候向右走得太远了。

It can even be too high up (line-height strikes again):
它甚至可能太高了(行高再次出现):

Horizontal centering 水平居中

You might think that only centering things vertically is hard. Not only! Horizontal might be hard, too:
你可能会认为只有垂直居中是困难的。不仅如此!水平居中也可能很困难:

I don’t think there’s a deep reason for these, except for people just being sloppy:
我认为这并没有深层原因,除了人们做事马虎。

Just, come on! 来吧!

Can this be a deliberate decision?
这可能是一个故意的决定吗?

I don’t know. Icons can suffer from it, too:
我不知道。图标也可能受到影响:

As can text: 如下文:

What can be done: designers
可以做的事情:设计师

So what is the problem?
那么问题出在哪里?

It all starts with the font. Right now, the bounding box of a text block looks like this:
一切都始于字体。现在,文本块的边界框看起来是这样的:

The problem is, it can also look like this:
问题是,它也可能看起来像这样:

or this: 或者这个:

Now, what will happen if you try to center text by centering its bounding box?
现在,如果您尝试通过居中其边界框来使文本居中,会发生什么?

The text will be off! Even though rectangles are perfectly centered.
文本会偏移!即使矩形完全居中。

But even if font can have its metrics unbalanced, it doesn’t mean it does. What happens in reality?
但即使字体可能存在不平衡的度量,也不意味着它确实存在。实际上会发生什么?

In reality, most of the popular fonts have metrics slightly off. Many have it significantly off:
实际上,大多数流行的字体都有略微偏差的度量。许多字体的偏差相当大。

Percentages are of cap-height
百分比是以大写字母高度为基准的

10% is not a small number. It’s a whole pixel in font size 13! Two, if you have 2× scaling! It’s easily noticeable.
10%不是一个小数字。在字体大小为 13 的情况下,它是一个完整的像素!如果你有 2×的缩放,那就是两个像素!这很容易被注意到。

Basically, Segoe UI is the reason why Github on Windows looks like this:
基本上,Segoe UI 是 Github 在 Windows 上看起来像这样的原因:

The solution is simple: make tight bounding boxes and centering will become trivial:
解决方案很简单:制作紧凑的边界框,居中将变得微不足道:

If you use Figma, it already can do this (although it’s not the default):
如果你使用 Figma,它已经可以做到这一点(尽管这不是默认设置):

What can be done: font designers
可以做的事情:字体设计师

If you are a font designer, make life easier for everybody by setting your metrics so that ascender − cap-height = descender:
如果您是字体设计师,请通过设置您的度量标准来为所有人简化生活,使 ascender − cap-height = descender

Or the same idea, visually:
或者同样的想法,视觉上:

Important! You don’t have to actually extend your ascenders/descenders to these boundaries. As you can see in the picture, my ascender space, for example, is way underutilized. Just make the numbers match.
重要!您实际上不必将您的上伸线/下伸线延伸到这些边界。正如您在图片中所看到的,例如,我的上伸线空间利用率远低于标准。只需使数字匹配即可。

For both web and native, to avoid headaches, choose a font that already follows this rule. SF Pro Text, Inter, and Martian Mono seem to do this already, so they will center perfectly with no extra effort.
无论是网页还是原生应用,为了避免麻烦,请选择一个已经遵循这一规则的字体。SF Pro Text、Inter 和 Martian Mono 似乎已经做到了这一点,因此它们将完美居中,无需额外的努力。

See Font size is useless; let’s fix it for more information.
请参阅字体大小无用;让我们修复它以获取更多信息。

What can be done: web developers
可以做的事情:网络开发者

From the developer side, it’s a bit more tricky.
从开发者的角度来看,这有点棘手。

The first thing to understand, you need to know which font you’ll be using. Unfortunately, this doesn’t work if you plan to substitute fonts.
首先要明白的是,你需要知道将要使用的字体。不幸的是,如果你打算替换字体,这种方法就行不通了。

We’ll use IBM Plex Sans, a font used on this very page. IBM Plex Sans has the following metrics:
我们将使用 IBM Plex Sans,这是本页面上使用的字体。IBM Plex Sans 具有以下度量标准:

When you set font-size, what you set is UPM (this will also be equal to 1em). However, the actual space occupied by the text block is the space between the ascender and descender.
当你设置 font-size 时,你设置的是UPM(这也等同于 1em )。然而,文本块实际占据的空间是基线和下行线之间的空间。

With a few simple calculations, we get that extra padding-bottom: 0.052em should do the trick:
通过简单的计算,我们得出额外的 padding-bottom: 0.052em 应该就可以解决问题:

Should work like this:
应该像这样工作:

Or in actual CSS (select text to see default text bounding box):
或者在实际的CSS中(选择文本以查看默认文本边界框):

Andy 安迪

You can get the required font metrics for your font from opentype.js.org/font-inspector.html (ascender, descender, sCapHeight).
您可以从opentype.js.org/font-inspector.html获取您字体的所需字体度量(上升高度,下降高度,小写字母高度)。

Now that we have that sorted, aligning icons is not that hard too. You set vertical-align: baseline and then move them down by (iconHeight - capHeight) / 2:
现在我们已经解决了这个问题,对齐图标也不是那么难。您设置 vertical-align: baseline 然后将它们向下移动 (iconHeight - capHeight) / 2

This, unfortunately, requires you to know both font metrics and icon size. But hey, at least it works:
不幸的是,这需要您了解字体度量和图标大小。但是,至少它起作用:

Andy  安迪

Again, select the text above to see how different the browser’s bounding box is from the correct position.
再次选择上面的文本,看看浏览器的边界框与正确位置有多大不同。

What can be done: icons fonts
可以做什么:图标字体

STOP. 停止。

USING. 使用。

FONTS. 字体。

FOR. 为了。

ICONS. 图标。

Use normal image format. The one with dimensions, you know? Width and height?
使用普通的图像格式。有尺寸的那种,你知道吗?宽度和高度?

Here, I drew a diagram for you, to help you make a decision:
这里,我为你画了一张图,帮助你做出决定:

Just look at how hard Apple tries to put the checkmark inside the rectangle, and the rectangle next to the text label:
看看苹果是如何努力将勾号放在矩形内,并将矩形放在文本标签旁边的。

And they still fail!
他们还是失败了!

Nothing is easier than aligning two rectangles. Nothing is harder than trying to align text that has an arbitrary amount of empty space around it.
没有比对齐两个矩形更容易的事情了。没有比尝试对齐周围有任意空白空间的文本更困难的事情了。

This is a game that can’t be won.
这是一个无法赢得的游戏。

What can be done: optical compensations
可以做什么:光学补偿

We, developers, can only mathematically align perfect rectangles. So for anything that requires manual compensation, please wrap it in a big enough rectangle and visually balance your icon inside:
我们开发者只能在数学上对齐完美的矩形。因此,对于任何需要手动补偿的事情,请将其包裹在足够大的矩形中,并在其中视觉平衡您的图标:

What can be done: everyone
什么可以做:每个人

Please pay attention. Please care. Bad centering can ruin otherwise decent UI:
请注意。请关心。糟糕的居中会破坏原本体面的用户界面:

But a properly aligned text can make your UI sing:
但正确对齐的文本可以让您的用户界面更加出色:

Even if it’s hard. Even if tools make it inconvenient. Even if you have to search for solutions. Together, I trust, we can find our way back to putting one rectangle inside another rectangle without messing it up.
即使很难。 即使工具让它不方便。 即使你必须寻找解决方案。 我相信,我们可以一起找到办法,把一个矩形放进另一个矩形里,而不搞砸它。

I, for one, want to live in a world of beautiful well-balanced UIs. I trust that you do, too.
我个人希望生活在一个美丽、平衡的用户界面世界中。我相信你也是。

It’s all worth it in the end.
最终一切都是值得的。

Honorable mention 荣誉提名

Our article would be incomplete without this guy:
我们的文章如果没有这个家伙就会不完整:

Take care! 保重!

Hi! 嗨!

I’m Niki. Here I write about programming and UI design Subscribe
我是 Niki。在这里我写关于编程和 UI 设计的内容 订阅

I also create open-source stuff: Fira Code, DataScript, Clojure Sublimed and Humble UI. If you like what I do and want to get early access to my articles, you should support me on Patreon.
我还创建开源项目:Fira Code、DataScript、Clojure Sublimed 和 Humble UI。如果你喜欢我的作品,并想提前获取我的文章,请在 Patreon 上支持我。