你看这个东西是不是没居中

·  阅读 280

前端切图仔还原UI设计师的设计稿是对UI的一种尊重,不能还原那就是你太菜了。每次我们欢天喜地的去找UI走查的时候,UI是这样的

你一看代码:

.center {
  display: flex;
  justify-content: center;
  align-items: center;
}
复制代码

心中一惊:这都能对不齐,那一定是你的机子有问题,建议换一台,UI可能要让你当场横尸街头。今天我们来深究一下这个问题。

问题复现

首先我们把问题复现出来,我们不用搞什么花里胡哨的内容,直接一个span标签扔上来,你可能会说我傻,一个span和谁对齐,我们给它加个border试试 .border { border:1px solid black; } 我们来看效果,这是在华为Mate30自带浏览器中渲染的结果

如果你看不出有什么问题,那么我们再展示一下PC端chrome渲染的结果

能看出问题了吗?显然在安卓上渲染的文字,在content area(黑色方框的内容)中就已经不居中了,它会偏上,而我们后续的操作都是在对齐content area,所以我们没办法用CSS去解决这个问题,即使解决了也是一种hack的方式,因为CSS是没办法影响到content area的。那么什么可以影响到content area?字体可以,我们来试一试下面的代码,更改一下字体,我们看看现在在PC端会渲染成什么样子

.fantasy {
  font-family: fantasy;
}
复制代码

渲染出来是这个结果

那么我们此时有一个需求,很简单,用div实现一个button,里面的文字需要居中

.button {
  border: red 1px solid;
  width: 50px;
  height: 30px;
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 10px;
}
复制代码

我们来看看两种字体渲染的结果:

很明显,第一种字体没有实现居中,这是因为它在content area中本来就已经偏上了,所以当content area居中的时候,字体一定不可能居中。注意,这是在PC端渲染的结果。所以你能想到为什么移动端的文字不能居中的么?对,就是默认字体的问题。那么移动端的默认字体会是什么呢,不同手机厂商都不相同,因为国内安卓手机太多了,所以也就导致可能会选中content-area中的文字已经偏离的字体。

如果我们使用height和line-height相同的方式居中,文字会和在content-area中有相同的偏离。但是如果我们用flex去居中,确发现conten-area中的内容也偏离了,但是和直接渲染span偏离的又不同了。

比如下面这种:

这是通过设置height和line-height同高的居中方式,可以看到conten-area中的文字偏上导致没有居中 而这是在PC端的渲染效果

可以看到这是很完美的居中了

而当我们用flex布局去居中时,得到的结果是这样的

可以看到content-area中的文字偏下了.......所以导致整体渲染偏下了,为什么偏下,这个真涉及到了我的知识盲区,我只能把锅甩给安卓的渲染了。

网上说法

你拿着这个问题去google去百度,能得到这几种说法:

小于12px的文字会有这个问题

通过博客中放出的截图,确实在小于12px时content-area中的文字会偏离,但是大于12px就不会 但是在我的手机上,无论是多大都会出现偏离的现象。所以看看发文日期,只能说一句:时代变了,大叔

安卓寻找默认字体的机制有问题

文章链接放在了末尾,其实我觉得这篇文章说的有部分内容是对的,部分内容和我目前实验的结果不同,各位看官自行实验评判一下吧。

字体问题

我个人是最赞同这种观点的,这个问题不仅仅会出现在安卓上,也会出现在ios,PC端上。但是因为PC端,IOS端选择字体的时候可能有一套固定的机制,所以总能选中content-area内文字居中的字体,所以才能正常的居中。而安卓选择默认字体的时候百花齐放,导致content-area内的文字已经偏离了,后续进行任何修改都是没办法挽回的。

思考原因

为什么网上会出现这么多关于居中问题的说法,又各自给了解决方案,但是今天在我的手机上却没有效果。我个人觉得:这依赖于安卓渲染机制。各大手机厂商不能统一标准,所以可能会出现各种的渲染方式。我们看到的文章大多数是好几年以前的文章,手机几年的时间变化非常快,所以可能之前的有的问题现在没有了,之前的解决方案现在不行了,我更倾向于把这个没有居中的问题当作安卓的一个bug。

同时,我觉得最靠谱的就是安卓的字体渲染有问题,所以我们想要从根本上解决问题,那就得从字体入手,其他方式都没办法去解决这个问题。

尝试解决

指定默认字体

总而言之,就是安卓渲染的字体有问题...那么我们指定一个字体方正:

@font-face {
  font-family: fz;
  src: url('./font/fz.ttf') format('truetype');
}
.fz {
  font-family: fz;
}
复制代码

这是在PC上渲染的结果

这是在安卓上渲染的结果

可以看到,我们的居中已经不会出现偏差了,因为我们强制的去使用了同一种字体。那么我们现在再来尝试一下将文字和图标对齐。

可以看到我们的方正是没问题的,而默认字体会出现文字下沉的情况

放大两倍再缩小两倍

就我观察到的情况而言..这种方法并没有什么用,文字还是会下沉

而有时候这种情况确实有用,我个人觉得是因为我们在项目中使用的是rem,而rem到px的时候可能会产生很多奇怪的px数值,比如奇数和小数,这时候不同的手机可能会对这种px进行不同的处理。所以我们放大两倍相对于减少奇怪px出现的情况,让各种安卓机型尽量能对他进行一致的处理,当然,如果px解读正确了,但是字体还是不对,自然还是无法居中,所以表现就是没有任何效果。

用margin微调

别笑,我们试试,加一个margin-bottom: 2px 浏览器的效果:

安卓的效果:

IOS的效果

怎么样,视觉效果是不是还可以。但是你仔细观察就会发现,其实在浏览器和IOS上文字是偏上的,但是乍一看还是可以的。

完美解决方案

上面说的方案其实都不怎么样,有没有一种完美的解决方案呢?有,我们看这个 www.w3.org/TR/css-inli…

leading-trim这个属性的作用就是删除掉文本上下的空白,这样我们的content-area就完全等于我们的字体高度了,所以,我们居中的时候自然就能很完美的将文本居中,和小图标居中也自然是轻轻松松。

可惜的是目前这个属性还是草案的一部分,我们现在没办法直接使用他,所以还是只能用hack的方式去解决这个问题

总结

经过一番研究,我认为,这就是安卓的一个bug.........所以才会出现各种说法,也出现了各种解决方案,但是你去从尝试的时候又会发现,这玩意没用啊。 所以我们总结一下:

  1. 不要在移动端使用line-height,移动端的渲染方式已经够奇怪了,不要再给他增加不确定因素
  2. 使用rem时,为了确保最后的px值不那么奇怪,我们可以放大缩小两倍,但是不一定有用,或者直接使用px不要使用rem。这也可以解决12px以下的字体渲染错误的问题(虽然我还没能复现这个问题)
  3. 最后,我们可以通过margin去进行微调,让视觉效果在各端保持基本的一致

其实最好的方法还是指定字体,但是中文字体一般都很大,在加载时很慢,所以我们如果想指定字体,就必须要解决这个问题,而如何去解决字体加载的问题,这又是另一个问题了,不在我们这次的讨论范围之内。

参考资料

  1. imweb.io/topic/5848d…
  2. rprns.me/2018/07/27/…
分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改