你的垂直居中有问题?我竞无法反驳 ‍♂️

前言

我们平常实现的垂直居中不是真正的垂直居中?何出此言!很多时候,往往自己明明正确的实现了垂直居中,但是 UI/UX 依旧说你的垂直居中有问题,然后自己仔细一看确实好像在视觉效果上存在一些偏差,但是仔细看自己实现的垂直居中代码却丝毫没有问题。今天我们就探讨一下这个有趣问题的由来、解决方案以及文字排版的未来。

发现问题

垂直居中的方式有很多种,这里我们在父级元素使用 display:flex;align-items:center 属性对子元素进行垂直居中,如下图:

似乎这个垂直居中已经非常完美了,但是你却收到了来自 UI/UX 的反馈和质疑

UI/UX:咦?你这垂直居中有问题~🥴

开发:哪里有问题,代码完全没有问题啊~

UI/UX:不信你自己看,文字的上半边空白部分比下半边多了 1px

开发:还真是…😑终究是逃不过设计的眼睛啊~

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wTLRxSvj-1602404587365)(https://user-images.githubusercontent.com/44939961/95669115-7f6d8b80-0baf-11eb-8f65-f90f3799812b.png)]

而我们真正想要效果是下面这样的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HZphqWky-1602404587367)(https://user-images.githubusercontent.com/44939961/95670662-c44dee00-0bc0-11eb-827b-45e756f812fd.png)]

初探问题

细心的小伙伴,马上就会发现啊,罪魁祸首就是文本的 line-height 这个属性。那我们现在用 <p> 包含三个不同 font-family<span> 得到了下图这样的效果,对 font-size 相同的 font-family 不同的文本元素会产生具有不同高度。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NZgL1bRb-1602404587370)(https://user-images.githubusercontent.com/44939961/95669911-0161b280-0bb8-11eb-805a-bba1628141e3.png)]

问题找到了,导致垂直居中只是近似垂直居中的根本原因就是 line-height!在标准的文本框中,实际上文本上方和下方总是会有多余的空间,默认行高保留的多余空间会导致文本不总是在文本框中居中。因此,我们实现的垂直居中会存在不符合预期的情况,line-height 越大,问题就会越明显。同时,不同的字体,默认的 line-height 也会不同,因此,在字体大小,行高和文本框位置不变的情况下,更改字体也会导致文本的对齐结果。

🤯 这个问题就到此为止了吗?不,我们还不知道 line-height 为什么是这样的,以及为什么要这样。🤷🏻‍♂️

追根溯源

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vytow84p-1602404587374)(https://user-images.githubusercontent.com/44939961/95671006-b4380d80-0bc4-11eb-9f7f-132f664585be.png)]

大约140年前,印刷术仍然使用单个引线盒手动设置字体。在印刷时,为了使文本更具可读性,排字机将铅条(leading)插入空格线。因此,打印的文字高度加上铅条的高度的总和就是总行高。

80 年代早期的图形设计软件保留了相同的传统,人们可以直接添加底部 leading 来控制基线之间的间距,同时也导致 line height 的增加。其他软件则让人们可以在直接调整行高。例如,在 1990 年发布的 Photoshop 的第一个版本中,用户可以定义 leading 的值,然后将其添加到字体大小中。许多工具也开始两个基线之间的距离叫做 line-height

1989 年,当 Bert Bos 和 HåkonWium Lie 起草 CSS 的第一个提案时,起初他们仍然遵循印刷世界的“旧”方式。但是很快,他们将决定做出合乎逻辑的又是根本性的改变,将 leading 一分为二,并将其放在每行的上方和下方,称其为 “half-leading”。为什么要这样做呢?目的就是为了使文本框看起来均匀(https://www.w3.org/TR/CSS1/#the-height-of-lines)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wwJCK3f4-1602404587376)(https://user-images.githubusercontent.com/44939961/95671364-cddb5400-0bc8-11eb-9be1-a44d3115a9a6.png)]

”half-leading“ 非常取巧的避免了上下边框的不均匀性,但是同时也带来了一些问题。字体系列中的每种字体大小都带有默认的行高。为了容纳某些字符和重音符号,通常会将默认行高设置的高于其包含的文字。增加默认行高后再增加两个 “half-leading”,这样使得文本框变得更大了。这样一顿操作下来,就是我们现在面临文本无法垂直居中最根本的原因了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xG5xOeeU-1602404587377)(https://user-images.githubusercontent.com/44939961/95671399-33c7db80-0bc9-11eb-8b94-6d53c762e50f.png)]

多年来,Web 设计工具一直不支持半领先技术,因此,许多团队讨论了为什么屏幕设计和浏览器之间的布局差异如此之大。最重要的是,并不是每个人都知道这种复杂的技术细节,这经常导致设计师和开发人员之间容易发生一些口角🤦🏻‍♂️

解决方案

手动调整相关 CSS 属性

手动调整相关 CSS 属性,但是这样会出现一系列魔幻的 margin 或者 padding 的值,同时过于随机,并且只针对特定的字体、浏览器、操作系统。很明显这不是一个很好的解决方案。

裁剪工具

EightShapes Text Crop Tool

从工具中选择一种字体或加载自定义字体,然后使用滑块测量所需的顶部和底部裁剪。该工具会计算属性和公式,只需将生成的 SCSS,LESS 或 Stylus mixin 复制并粘贴到源代码中。

为什么只能针对一种字体,而不是所有字体都使用呢?

工具原理是通过 before 和 after 伪元素来定义负边距,这种做法在保留多行文本块中的行之间的行高的同时,删除了顶部和底部的空白。

// Top crop:
$ top-crop +($ desired-line-height-$ line-height-crop)*($ font-size-with-crop / 2)),0)/ $ font-size-with-crop;
//Bottom crop:
$ bottom-crop +($ desired-line-height-$ line-height-crop)*($ font-size-with-crop / 2)),0)/ $ font-size-with-crop;

最终结果是一个混合字体,无论字体大小如何都可以工作,并且只需要无单位的行高即可执行计算。但是将 mixin 应用于其他字体时,效果却不太好。

工具实现的是将 Em Square 裁剪为字体的 baseline 和 cap height,但是,每种字体都有不同的 Em Square Definition。因此,适用于一种字体的 “magic numbers” 不一定适用于其他字体。

新的 CSS 草案

很早开始就有很多人碰到了类似的问题,并且向 W3C 进行了反馈,我们不是第一个遇见这个问题的人。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-exZWo2uz-1602404587381)(https://user-images.githubusercontent.com/44939961/95672262-fc116180-0bd1-11eb-8bcb-6c5baa99ff34.png)]

为修复 CSS 文本布局相关问题,Leading-trim 成为了 CSS 内联布局草案的一部分

图片发布
h1 { 
 text-edge: cap alphabetic;
 leading-trim: both;
}

借助 leading-trim,最终可以解决在网站上看到的所有神秘的对齐问题。可以在不破坏设计意图的情况下更换字体。

a GIF of the same icon and type, where the typeface is changing, however the vertically centered alignment is perfectly preserved

以下是是 leading-trim 属性相关草案(尚未成为规范

Name:leading-trim
Value:normal | start | end | both
Initial:normal
Applies to:block containers and inline boxes
Inherited:no
Percentages:N/A
Computed value:the specified keyword
Canonical order:per grammar
Animation type:discrete
Name:text-edge
Value:leading | [ text | cap | ex | ideographic | ideographic-ink ] [ text | alphabetic | ideographic | ideographic-ink ]?
Initial:leading
Applies to:inline boxes
Inherited:yes
Percentages:N/A
Computed value:the specified keyword
Canonical order:per grammar
Animation type:discrete

Ref

Leading-Trim: The Future of Digital Typesetting
The 4px baseline grid — the present
Getting to the bottom of line height in Figma
The Thing With Leading in CSS
[css-inline] Leading control at start/end of block #3240
Intro to Font Metrics
Deep dive CSS: font metrics, line-height and vertical-align
CSS Inline Layout Module Level 3
Cropping Away Negative Impacts of Line Height

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值