CSS世界

内联元素与流

Posted on 2018-02-09,6 min read

字母x——css世界中隐匿的举足轻重的角色

我们这里的字母x就是我们平常所见的字母x,只不多由于它本身形态的特殊性,由此衍生出了许多的css概念。

x-height与ex

css中有一个概念叫做x-height,顾名思义就是字母x的高度,术语就是基线(baseline)和等分线(mean line)(也俗称中线midline)之间的距离。

维基百科有一个示意图:

字母x衍生出了x-height的概念,并在这个基础上有衍生出了ex单位,可能你还没听过,但是就连IE6都支持这个单位。那这个有什么用呢?要说运用在元素的尺寸控制上面,这个还不适合,因为ex受限于字体的影响,这就导致其不稳定性,这也是很多人没有听说它的原因,毕竟他没啥用,但是我们可以将其运用在副业上——不受字体和字号影响的内联元素的垂直居中对齐效果,关键代码:

HTML:
<p>这是文字<i class="icon-arrow"></i></p>
CSS:
.icon-arrow {
    display: inline-block;
    width: 20px;
    height: 1ex;
    background: url(/img/2018-2-10/arrow.png) no-repeat center;
}

效果:

这是文字

原理很简单,我们都知道默认内联元素默认基线对齐,而基线就是x的底部,而1ex就是一个x的高度,如果设置图标高度就是1ex,同时背景图片居中,岂不是刚好文字和图片垂直居中。

内联元素的基石line-height

对于非替换内联元素,内联元素的高度完全由line-height决定。
估计不少人认为内联元素的高度都是由内容决定的,不然为何空的div中写上几个文字,div的高度立马就显现出来了,这里我们来看一个具体的例子:

HTML:
<div class="test1">高度-1</div>
<div class="test2">高度-2</div>
CSS:
.test1{
    font-size:16px;
    line-height:0;
    border:1px solid #ccc;
    background:#eee;
}
.test2{
    font-size:0;
    line-height:16px;
    border:1px solid #ccc;
    background:#eee;
}

效果:

高度-1

高度-2

由上可以看出,两个div的元素在于line-height行高是否为0与font-size是否为0,第一个由于行高为0,导致其高度几乎看不见,高度即为背景为灰色的部分,第二个虽然字体大小为0,但是其行高不为0,使其背景撑开16px的内部高度,足以证明非替换元素的元素的高度完全由行高决定,而不是我们平常所说的font-size决定。

了解了这个原理后,我们就可实现一个基于多行文字的垂直居中效果。

HTML:
<div class="box">
    <div class="content">基于行高实现的多行文字垂直居中效果,需要vertical-align属性帮助。</div>
</div>
CSS:
.box {
    width: 280px;
    line-height: 120px;
    background-color: #f0f3f9;
    margin: auto;
}
.content {
    display: inline-block;
    line-height: 20px;
    margin: 0 20px;
    text-align: left;
    vertical-align: middle;
}

效果:

基于行高实现的多行文字垂直居中效果,需要vertical-align属性帮助。

原理很简单,通过设置.box的行高120px,使其撑开为120px高度,注意这里的高度是作用于幽灵空白节点而言的,相当于在.content元素前面撑开了120px高度的内联元素。最后通过设置内联元素的vertical-align:middle来调整多行文本的垂直位置。当然,这里的垂直居中只是近似的垂直居中,因为我们都知道vertical-align:middle对齐位置是小写字母x的交叉点,并不是我们想象中的一个字母的中线位置。

深入line-height的各类属性值

line-height的默认值是normal,还支持数值、百分比以及长度值。很多人可能对这默认值都假象为某一定值,大概也就1倍多一点的样子,但其实normal是一个变量,并且和font-family有着密切关联的变量值。考虑以下几段代码:

div{
    line-height:normal;
    font-family:'miscrosoft yahei';
}
div{
    line-height:normal;
    font-family:simsun;
}

下表是在几个桌面浏览器上面的测试数据,其显示了normal的计算值的区别。

字体 chrome Firefox IE
微软雅黑 1.32 1.321 1.32
宋体 1.141 1.142 1.141

鉴于每个浏览器的表现不一,所以重置样式那肯定是必要的,但重置为多少又是一个问题,lien-height支持三种类型的数值,其中数值类型继承细节与其他两种有所区别,具体表现在:

以数值作为line-height的属性值,其子元素继承的都是这个值;以百分比值和长度值作为line-height的属性值,其子元素继承的是最终的计算值。

因此我们一般都可以这样设置值:

body{
    line-height:1.5;
}
input,button{
    line-height:inherit;
}

如若我们要设置固定的line-height20pxfont-size的值为14px,那么行高则为20/14≈1.4285714,为兼容谷歌,向上取值,则最终设置的样式为:

body{
    line-height:1.42858;
    font-size:14px;
}

line-height和vertical-align

vertical-align的百分比值是相对于line-height的计算值计算的,这个可能许多人都不清楚,设置vertical-align起作用的先决条件只能应用于内联元素以及display值为table-cell的元素,并且浮动和绝对定位会让元素块状化,导致vertical-align依旧失效。

最后展示一个基于vertical-align的水平居中弹框,具体可查看这个demo

参考自《css世界》

作者:落叶卢生
链接:https://luoyelusheng.com/post/内联元素与流
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

下一篇: 基础知识与盒尺寸→