意见箱
恒创运营部门将仔细参阅您的意见和建议,必要时将通过预留邮箱与您保持联络。感谢您的支持!
意见/建议
提交建议

CSS世界Bug般的存在——字母x与“居中”

来源:恒创科技 编辑:恒创科技编辑部
2024-01-09 03:51:59


字母x ?

《css世界》中提到:“我们这里的字母x就是26个英文字母中的x。由于自身形态的一些特殊性,这个小小的不起眼的字母担当大任,在css世界中扮演了一个重要的角色。”


CSS世界Bug般的存在——字母x与“居中”


笔者在这两天写一个项目中遇到了“居中”的困惑:我发现代码段

li{
verticle-align: middle;
}

失效!

经过一番查证,发现:vertical-align属性只对行内元素有效,对块元素无效
但我很快想到:有时候为什么写了line-height也会出错、或者说反而会出错呢?

有时使用display:inline-block会导致verticle-align:middle失效。为何?因为display:inline-block会导致line-height有偏差

这又是什么原理?

CSS世界Bug般的存在——字母x与“居中”_css

字母x与“基线”

在各种内联相关模型中,凡是涉及垂直方向的排版或者对齐的,都离不开最基本的——基线。

例如,​​line-height​​​行高的定义就是两基线的间距,​​verticle-align​​的默认值就是基线;其它中线顶线一类的定义也离不开基线。

基线也延伸出了很多其它的概念:

比如字母基线悬挂基线表意基线

CSS世界Bug般的存在——字母x与“居中”_verticle-align_02

而【基线】的定义就离不开本文的主角“X”。

字母x的下边缘(所在直线)就是我们所说的基线

上面所说内容当然和开头的“问题”没有直接关系,但是它确实引出了下面的一系列概念:

CSS世界Bug般的存在——字母x与“居中”_line-height_03

字母x与CSS中的x-height

要更深层次的了解字母x,或者说基线与居中有何关系,那就不得不说CSS中的一个概念——x-height
它指的是字母x的高度!

通俗的讲,x-height就是指小写字母x的高度,术语描述就是基线和等分线(也叫“中线”)之间的距离:

CSS世界Bug般的存在——字母x与“居中”_css_04

为什么要说这个?
CSS中有些属性值的定义其实就和这个​​​x-height​​​有关,最典型的代表就是​​verticle-align: middle;​​​。这里的middle是中间的意思。注意:跟上面所说【中线】不是一个意思(图中baseline上面那根就是median——中线)。
在CSS中,middle指的是基线往上1/2 x-height高度的位置。我们可以近似理解为“字母x的交叉点所在位置”。

由此可见,​​verticle-align: middle​​ 并不是绝对的垂直居中对齐 —— 我们平时看到的middle效果只是一种近似效果。原因很简单:不同字体在行内盒子中的位置是不一样的。

事实上,“微软雅黑”是一个字符比较下沉的字体——所有字符的位置都比其它字体要偏下一点。

也就是说,“微软雅黑”字体中的字母x的交叉点是在容器中分线的下面一点。而此时我们就不难理解为什么verticle-align不是相对容器的中分线对其的了。

让我们回到开头的一段代码,我们此时可以很容易想到:先将其变为行内

li{
display: inline-block;
verticle-align: middle;
}

发现没啥用。。。
然后我们“恍然大悟”,想到:这是缺少“参照”的表现啊!

而对于li列表,适合用什么布局呢?——table:

li{
display: table-cell; /* 转化为单元格 */
verticle-align: middle;
}

其实line-block失效的原因有很多:比如你再元素外层又包裹了div,对div设置display、本来就是line…这里是恰好碰上li罢了

这样就解决了。

CSS世界Bug般的存在——字母x与“居中”_line-height_05

字母x与CSS中的ex

我们可能都听过em、rem、px、rpx,但是这个ex是什么鬼。。。
说起这个,他可能就会很自豪:毕竟是连IE6都支持的属性单位。

ex是CSS中的一个相对单位,指的就是小写字母x的高度。没错,就是指x-height。
而且——不受字体和自号影响的内联元素的垂直居中对其效果!

我们都知道,内联元素默认是基线对齐的,而基线就是x的底部,而1ex就是一个x的高度。设想一下,假如图片(标)的高度就是1ex,将其作为背景图片显示,这时如果(背景)图片居中,那岂不是图标和文字“天然”垂直居中对齐?而且不受字体和自号的影响。

<div class="mxc">
yunxiaomeng<i class="icon-arrow"></i>
</div>
<style>
.icon-arrow {
display: inline-block;
width: 20px;
height: 1ex;
background: url("/img/up.png") no-repeat center/20px 20px;
}
</style>



然后就对齐了 —— 完全没有verticle-align的出场机会嘛!


当然,关于“居中偏差”的问题我们也可以用伪元素解决,比如这里:

li:after{
content: "";
display: inline-block;
height: 100%;
vertical-align: middle;
}



上一篇: 对 Go2 错误处理提案的批判 下一篇: 小小小tip:避免滚动条显隐对页面其他元素的影响