寻根究底之line-height与vertical-align
# 前言
在CSS中存在这样一些被广泛使用的简单属性,简单到以至于我们绝大多数人都坚信自己能够完全理解它们的工作原理和使用方法。line-height
和vertical-align
就是这些属性中的两个。事实上这两个属性非常复杂,它们共同作用的机理,甚至可以说是CSS中最复杂的组合之一。因为它们创建的一个鲜为人知的特性在CSS中扮演着无比重要的角色,那就是内联格式化上下文
(opens new window)。
如果仔细地回想一下,你一定在实际工作中遇到过以下几个问题:
- 设置了
vertical-align:middle
却没有居中 - 图片的周边存在一个间隙
- 两个设置了
display:inline-block
的元素错位了 - 跟随文字的图标无法完美的居中
当遇到这些问题时,也许你通过各种各样的尝试(如负margin等)解决了问题,也许你找不到解决的方法而不得不换一种实现的方式。如果不深入的去理解line-height
和vertical-align
实际作用的机理,那么在使用它们的时候就会屡屡遇到难以解决的问题。本文就详细地解析line-height
和vertical-align
这两个属性以及它们共同作用的原理,彻底解决使用它们的过程中遇到的疑难杂症。
在解析line-height
和vertical-align
之前,你最好已经了解了以下几个知识:
- 行内格式化上下文(Inline formatting context) (opens new window)
- 文字、段落以及字体设计的特性
- CSS中常见文字单位的使用方式
display:inline-block
起作用的前提条件
鉴于篇幅的问题,我另写了一篇文章《文字特性与CSS单位》专门来介绍以上相关部分的知识,本文仅针对此部分内容作简单的介绍。
# 一、 几个概念
行高: 指内容区与以内容区为基础上下对称拓展的空白区域组成的区域高度。现在普遍的认为行高是相邻两行文本基线之间的距离。
基线: 即
baseline
,是文字排版中的概念,指在文字排版时,小写字母x底部所在的位置。说到基线,就不得不请出以下这张图,图片展示一个正常的文本排版中,各种线以及高度的定义。
x-height:如上图,
x-height
是指baseline
与mean line
的距离,指的是小写字母x
的高度。四种内联盒子
内联格式化上下文(IFC)
中盒子的概念,包含四种内联盒子,分别是containing box
, line box
, inline boxes
, content-area
。分别如下:
(1) inline boxes: 行内框,正常文档流中一个接一个排列的框,这些框不会成块显示,而是并排显示在一行的,如span
,a
,em
等标签以及匿名节点(即不被标签包裹的的文字节点)。
(2) line box: 行框,由一个个的inline boxes
组成的框,一行即为一个line box
。单个line box
的高度是其内容的最低点与最高点的距离。通常是由其包含的所有inline boxes
中高度最大的那个决定(由line-height
起作用,后面解释)。
(3) containing box: 所有的boxes排列堆叠后形成的最外层的框,所有line box
的高度堆叠成了containing box
的高度
(4) content area重要: 围绕文字看不见的框,其大小与font-size
和字体本身的设计有关,一般情况下我们无法使用CSS来控制,如下图,三种不同字体,font-size
都为100px的文字,其content-area
是不一样的
以下为几种boxes的关系(图片中,粉红色假设为content-area所在区域
)
<div>
这里是一个div,里面包含了独立的文字,
<span>span标签</span>
<em>em标签</em>,
以及其他的一些文字。
</div>
2
3
4
5
6
提示
理解四种box非常重要,平时使用浮动,定位,元素高度计算等表现都与这几种盒子密切相关。
# 二、深入理解行高line-height
# 1. line-height 与 line box的高度关系
在介绍完内联盒子之后,应该有不少人认为,line box
的高度是由内部文字撑开的,也就是说其高度由文字的大小(即font-size
属性)来决定,文字的大小越大,line-box
的高度就越大。然而实际上line box
的高度与文字大小并无直接的联系,而是由文字的line-height
来决定的。我们通过以下几个例子比较,证明这个结论。
<div class="div div1">我是一行文字大小为30px,但是line-height为0的文字</div>
<div class="div div2">我是一行文字大小为0,但是line-height为100px的文字</div>
<div class="div div3">我是一行文字大小为30px,line-height都为100px的文字</div>
2
3
4
5
.div {
background: #f0f0f0;
border: 1px solid green;
margin: 30px;
}
.div1 {
font-size: 30px;
line-height: 0;
}
.div2 {
font-size: 0;
line-height: 100px;
}
.div3{
font-size: 30px;
line-height: 100px;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
结果表现为:
图中的绿色矩形的高度可以视为line box
的高度。结果显而易见,当文字的行高为0时,就算它的字号大小很大,line box
的高度为0。相反,即使字体大小为0,但如果行高不为0,则会撑开标签的高度。
从上图我们还发现,行高还有一个特性就是垂直居中性,针对每一行文字,无论line box
的高度是多少,其里面的文字都是公用一条垂直居中线,利用这一个特性,我们还可以实现一些近似的垂直居中效果(为什么近似,后面解释)。
注意
line-box高度真实的计算是其内部最低点与最高点的距离。本例子讨论的前提是字体的baseline是一致的(通常是同一字体)。但无论何种情况,line-height
就是line-box高度计算的决定性因素
# 2. 文本间距
两行文本之间的间距称为文本间距,在印刷排版中,指的是两行文字基线的距离,称为leading
。在CSS中,文本上下的间距均为文本间距的一半,即通过设置行高后,行高与字体大小差值将等分于文本上下。设文本顶部和底部的间距为x,行高为y,字体大小为z,则满足:
2x + z = y
,也就是 x = (y - z) / 2
。这就是为什么有时候我们在设置样式的时候文本的字体大小大于行高,导致多行文本会重叠在一起的现象(见下文例子)。
# 3. line-height值为1.5
,150%
和1.5em
的区别
我们在给line-height
赋值时,经常设置类似1.5
,1.5em
,150%
的值。弄懂这几个属性值的区别同样非常重要。line-height
属性值具有继承性的,即父级设置的属性值会在子级中继承。几个属性的区别在于1.5是在子级继承后会重新根据自身的字体大小重新计算行高值,而1.5em和150%则会在父级计算完行高值后,原封不动的作用于子级元素。看以下例子,可以形象的说明这一特点。
上图可以看到,当父级元素字体为16px,行高为150%(即16x150%=24px)
时,最终行高24px将会被子元素继承,由于子元素的字体大小为32px,行高小于字体大小,根据上面第2点“文本间距”的计算公式我们可以得到,两行文字之间的距离为2x = 24 - 32 = -8px
,所以两行文字重叠在了一起;而当line-height
为1.5时,由于子元素会根据自身字体的大小重新计算行高,即2x = (32 * 1.5) - 32 = 16px
,得到两行文字之间的距离为16px,文本将不会重叠在一起。1.5em与150%同理。
因此,我们在实际使用的过程中,为了避免因为继承的原因引起的行高计算不符合预期,绝大部分场景应该尽量的少用em和百分比值作为line-height
的值,而使用1.5,2等不带单位的值替代。浏览器默认是line-height:normal
,这个值具体是多少与字体本身的度量属性有很大的关系,且不同浏览器也有差异,但其最终都会转为纯数字计算,W3C标准建议使用的值是1.0-1.2
之间的数字。因为line-height
的继承性以及浏览器的差异问题,著名的normalize.css
会有以下重置代码:
/**
* v8.0.1
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
2
3
4
5
6
7
8
9
提示
《文字特性与CSS单位》详细介绍了line-height:normal
具体的值是多少的计算规则。
# 三、深入理解vertical-align
初学者使用vertical-align
属性时,经常会发现最终的表现结果并不如预期,“vertical-align无效”也是CSS问题里搜索频率比较高的一个。大部分是因为对于该属性理解不够透彻引起的,只有理解了该属性的特点、表现行为以及与其他属性(如line-height
)的共同作用机制和效果,才能很好的解决vertical-align
带来的一些问题,并有效的利用它。
# 1. 起作用的前提
vertical-align
起作用的前提是元素为inline水平元素或table-cell元素,包括span
, img
,input
, button
, td
以及通过display改变了显示水平为inline水平或者table-cell的元素。这也意味着,默认情况下,div
, p
等块级元素设置vertical-align
无效。
# 2. 取值
vertical-align可以有以下取值方式:
(1)关键字: 如 top
, middle
, baseline(默认值)
, bottom
, super
, sub
, text-bottom
, text-top
(2)长度值: 如10px,-10px(使元素的基线对齐到父元素的基线之上的给定长度。可以是负数)
(3)百分比值: 如10%,根据line-height
作为基数进行计算后的绝对值,再以(2)的方式对齐
# 3. 各种属性设置后的表现形式
平时,我们用得最多的应该是top
,bottom
,middle
,baseline
等几个关键字。而长度值等用得比较少。以下通过例子展示一下各个值的表现形式,并做解析。
提示
以上所有外层标签的行高为100px,背景为灰色,所有的对齐方式为对图片进行设置,红色背景文字为图片的兄弟标签span,完整源码请看这里 (opens new window)。
各个属性值的表现如下:
(1)baseline: 默认的对齐方式,基线对齐,元素基线与父元素的基线对齐;
(2)top: 元素顶部与整行的最顶端对齐,一般是与行中的最高元素的顶端对齐;
(3)middle: 元素中部与父元素中线对齐(父元素基线往上二分之一x-height
高度处);
(4)bottom: 与top
相反,元素底部与父级元素的最底端对齐 ;
(5)text-top: 元素顶部与父级元素字体顶部对齐(content-area顶部),不受行高以及周边其他元素的影响。
(6)text-bottom: 与text-top
相反,始终与父级元素字体底部(content-area底部)对齐。
(7)super与sub: 使元素的基线与父元素的下标或上标基线对齐。类似super
标签和sub
标签,但不缩放字体大小。
(8)数值与百分比: 使元素的基线对齐到父元素的基线之上的给定长度。当数值为正值时,对齐方式将以基线为基准,往上偏移响应的大小,当为负值时,往下偏移。而百分比则是以行高为基数
,计算出响应的数值,再以数值表现的方式进行偏移。
通过观察,我们发现text-top
与top
,text-bottom
与bottom
这两对属性值,其表现在视觉上似乎没有任何区别。这是因为我们设置的字体大小和行高还不足以明显看出它们的区别。这两对属性值最大的区别在于text-top
和text-bottom
是相对于父元素的字体顶部或底部而言的,即相对于content-area
而言;而top
和bottom
是相对于整行的顶部或者底部而言。要看出它们的区别,我们仅需将文字的行高或者字体大小调大即可。以下我们将行高调整为100px来观察效果:
可以看到,当图片对齐方式是top
时,图片的顶部与文字所在的line box
的顶部对齐;当图片的对齐方式是text-top
时,其是不受行高影响的,图片的顶部与文字的顶部对齐,因此图片的顶部会多出来一段间隙。text-bottom
与bottom
同理。
在讨论vertical-align
各种对齐方式的时候,我们会区分是以父元素为基准还是以行(line box
)为基准。比如居中对齐,是以父元素为基准的。那父元素的各种线又是怎么定义的呢?关于这个父元素我搜遍了无数的资料,竟未发现任何关于这方面定义的内容。但如果不找出这个父元素各种线(如中线、基线)的位置在哪里,那么对于理解vertical-align
各种对齐方式的表现是很不利的。目前,通过具体实例在Chrome和Firefox的运行后的结果,根据我个人的理解,对父元素基线、中线等做一个简单的定义。
非权威定义
父元素的基线是指父元素内容为空时,空白节点(宽度为0的看不见的字符)的基线。同理,父元素的中线、下标基线也都是以这个空白节点的中线、下标基线等同。空白节点虽然宽度为0,但其继承了元素的行高等属性。
# 四、line-height与vertical-align的密切关系与应用
以上已经详细介绍了line-height
和vertical-align
的相关特性。咋一看,我们很难看到这两个属性之间的关系,但是实际上,这两个属性的关系非常密切,而且无处不在。我们在处理内联元素的对齐,排列时,很多令人捉摸不透的奇怪现象基本上都能从它们身上找到原因和解决办法。
# 1. 几个定义
在讲两个属性之间的关系和应用之前,先来了解几个定义。
(1)inline-block基线: 在CSS2可视化格式模型文档中,指出了inline-block
的基线是正常流中最后一个line box
的基线,但是,如果这个line box
里面没有inline boxes
或者其overflow
属性值不是visible
,那么其基线就是元素的底部边缘。原话如下:
CSS2规范
https://www.w3.org/TR/CSS2/visudet.html#leading (opens new window)
The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible', in which case the baseline is the bottom margin edge.
那怎么来理解这个规范的定义呢?我们用一张图片说明一下:
此处有两个inline-block元素,其中第一个有4行文字(即4个line box
),第二个是空的元素。绿色线就分别是它们的基线所在位置。对于第一个元素,其基线所在的位置就是最后一个line box
的基线所在位置;而第二个元素的line box
中不存在inline boxes
,那么其基线就是它的底部边缘所在的位置。
(2)middle对齐: 指元素的垂直中心线与父级基线往上二分之一X所在的位置的线对齐。有点绕,看下图:
(3)文字偏移特性: 文字是具有下沉或上升的特性的,就是文字的垂直中心点在文字所在区域(content-area)的中线往上或往下偏移一点,不同字体的文字一篇的幅度不同,同时,文字大小越大,偏移越明显。比如微软雅黑字体是一种具有下沉特性的字体,文字的视觉上的中心点会比其所在的区域的中心点(content-area中心点)往下沉一点。如上图,X的中线点相对白色中线往下沉。
# 2. 透过现象看本质
我们先通过例子来看看几个现象。
<div class="wrap">
<img src="xxx.png" />
</div>
<div class="wrap">
<span></span>
<span>我有内容</span>
</div>
<div class="wrap" style="height:200px;">
<img src="xxx.png" class="middle" />
</div>
2
3
4
5
6
7
8
9
10
.wrap {
background: #249ff1;
}
span {
display: inline-block;
widht: 100px;
height: 100px;
border: 1px solid #f00;
}
img {
width: 100px;
}
.middle {
vertical-align: middle;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
以上代码最后结果如下:
- 放在div里面的图片,在底部会多出一点空白间隙
- 两个样式一样的
span
,一个有文字一个没有文字,我们的意愿是想让两个span并排显示,但结果错位十分严重。 - 图片设置了居中对齐,但似乎没有生效。
要解释清楚以上的现象,就必须弄清楚vertical-align
和line-height
共同作用的机理。我们从第一个例子开始,一步一步的分析一下。
首先,通过上文可以知道,元素默认的对齐方式是基线对齐,即vertical-align: baseline
。而在浏览器中,所有的文字都有默认大小(占据的空间大小,本质上是line-height
决定的),这个空隙就是来源于这两个特点相结合产生的。为了便于我们观察,我们把外层容器的行高设置为一个相对大的值,在这里我们设置为50px。设置后表现如下:
可以看到,此时图片底部的空白间隙变得更大。既然间隙是由于文字的大小产生的,例子1里仅有一张图片,并不存在文字,不应该是没有影响吗?实际上,还存在着一个零宽字符(上文提高的看不见的节点)。这个特殊的空白节点与普通文节点一样,具有文字大小,行高,但宽度为0。因此,我们可以利用普通文本来代替这个节点来观察现象。我们在图片的后面加入一串字符。如下:
接着,我们再用一个设置了display:inline-block
的span
标签将文字包裹并设置文字背景色。如下:
经过以上两步改变,我们发现,图片的位置没有发生任何的变化,底部的间隙大小也没有变化。此时,已经足以解释为什么只有一个img
标签的情况下,图片底部会出现间隙:由于空白节点的存在,图片后面相当于跟了一个文本节点。而默认情况下,图片的对齐方式是以父级元素的基线对齐,为了保持与基线对齐,图片底部必须留出间隙,大小为上面提到的半倍文本间距(即(line-height - font-size) / 2
)。从公式可以得知line-height
的值越大,间隙将越大。知道了这些,结合我们上面对属性值特点的一些分析,要找到问题的解决办法就变得相当简单了。要去除图片底部的间隙,只需要将line-height
和vetical-align
属性的其中一个给干掉就可以了。可以有以下几种方法:
解决方案
(1)将图片设置为display:block
(利用vertical-align
的生效前提)
(2)将vertical-align
设置为top
,bottom
,或者middle
等值(利用属性值的表现行为)
(3)将line-height
设置为0(利用line-height
为0时,基线上移的特点)
(4)将font-size
设置为0 (利用纯数字格式的line-height
计算规则,默认值normal
本质上就是一个纯数字)
(5)将img
设置浮动或者绝对定位(使img
脱离正常的文档流,实际是破坏了line box
)
现在,利用第二种方法,将vertical-align
设置为bottom
,设置后结果如下:
有了例子1的分析,例子2的问题也能顺理成章的解决。由前面关于CSS2规范中对于inline-block基线
的定义可知,对于有内容的inline-block元素
,其基线为最后一行文本基线所在的位置,而对于空白的inline-block元素
,其基线为底部边缘所在位置。因为默认情况下为基线对齐,这两条基线对齐后就形成了上图那种错位的现象。所以解决办法是仅需将对齐方式设置为bottom
,middle
,top
等值就可以了。现在设置为middle
。效果如下:
至于第三个例子,有点让人摸不着头脑,这也是“vertical-align无效”被提问的最多的一种现象。按照vertical-align
生效个条件可知,给img
设置middle对齐后理论上应该是居中对齐才对,但为什么没有起作用呢?是真的没有起作用吗?答案是:起作用了。实际上,vertical-align:middle
是起作用了的,但至于最后图片为什么没有在父级里面垂直居中,是因为后面的空白节点高度不足,导致基线偏上,按照中线的定义,中线也是偏上(本质也是父元素基线定义)。我们可以用一个字母x代替后面的空白节点,来观察现象。
从图中可以看到,实际上图片与文字确实是垂直居中对齐了。这个居中的计算方式如下:
(1)确认父级的基线。在没有图片的情况下,父级标签的基线为空白节点的基线,中线为该基线网上二分之一x-height
的高度所在处(即X的中点)
(2)默认情况下,图片将与空白节点基线对齐,并形成一个line box
(3)vertical-align:middle
按照标准是当前元素的中线与父元素的中线对齐
(4)设置居中线对齐后,为了使图片的中线与空白节点的中点对齐的效果,图片就会下移一定的空间直至达到效果(相当于基线下移了)
(5)由于父级元素高度足够大,所以足以容纳空白节点所占据的空间(line-height
)决定,就会出现下方多余的空间。而实际上图片与空白节点形成的line box
里,内容已经是居中对齐。
由于图片在line box
里是居中对齐的,因此我们仅需让line box
的高度等于父级元素即可实现让图片在整个父级元素里居中。按照line box
高度的计算规则,我们可以将行高设置为父级的高度。效果如下:
此时,我们可以看到,图片“近似”垂直居中在了父级元素。这是因为设置行高后,根据之前分析的line-height
等于font-size
+2倍的文字上下间距
可知,父级基线往下。中线为基线往上二分之一x高度,此时图片的中线就与后面的x中线点对齐,实现了近似垂直居中的效果。
- 应用
利用空白节点这个特性,以及line-height
和vertical-align
的关系,我们可以做一些实际的应用。
(1) 实现垂直居中
由于空白节点存在,当我们给外层标签设置一个较高的行高值时,由于行高的上下间距平分的性质,可以实现近似垂直居中的效果。此时,也不需要给父级标签设置具体的高度值(因为line-height
会撑开父级)。
<div class="wrap">
<img src="@img/css/xx.png" class="middle"/>
</div>
2
3
.wrap {
background: #249ff1;
margin: 10px;
line-height: 200px;
text-align: center;
}
.middle {
vertical-align: middle;
}
2
3
4
5
6
7
8
9
(2) 任意父级高度的垂直居中
在上面的提到的三种现象中,第三个例子,我们给父级设置line-height
的值等于height
的值,实现了近似垂直居中的效果。那如果父级的高度是随着内容的变化而变化的怎么办?此时无法给父级行高设置一个特定的值,也不能使用百分比,因为line-height
设置百分比是根据字体的大小来计算的。换个角度想,空白节点我们看不见,但是如果可以给它设置一个高度,让它与父级高度一致,就解决了这个问题。怎么给高度呢?答案是借助辅助元素,我们可以在父级最后面增加一个display:inline-block
的span标签或者伪元素(通常使用伪元素),并设置height:100%;font-size:0
,接着让居中的元素居中对齐即可。
<div class="wrap" style="height:200px;text-align:center;">
<img src="../.@img/css/zhuyin.png" alt="" class="middle">
<span style="display:inline-block;height:100%;vertical-align:middle;font-size:0;"></span>
</div>
2
3
4
5
(3) 实现多图列表的两端对齐
在做类似商品列表的布局时,我们时常需要列表的每一行两端对齐。实现的方法有很多(比如flex布局),这里我们用display:inline-block
+辅助元素
来实现。如下:
<ul>
<li><img src="../.@img/css/zhuyin.png"></li>
<li><img src="../.@img/css/zhuyin.png"></li>
<li><img src="../.@img/css/zhuyin.png"></li>
<li><img src="../.@img/css/zhuyin.png"></li>
<li><img src="../.@img/css/zhuyin.png"></li>
<li><img src="../.@img/css/zhuyin.png"></li>
<li><img src="../.@img/css/zhuyin.png"></li>
<span class="fix"></span>
<span class="fix"></span>
<span class="fix"></span>
</ul>
2
3
4
5
6
7
8
9
10
11
12
li{
list-style-type: none;
border: 1px solid red;
display: inline-block;
width: 28%;
text-align: center;
}
.fix {
display: inline-block;
width: 28%;
text-align: center;
}
ul {
width: 720px;
border: 1px solid #a7a7a7;
text-align: justify;
margin: 20px auto;
}
li img {
width: 95%;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
结果如下:
每个图片的下方会有一个空白,前面已经解释过空白的来源,我们给ul设置line-height:0
即可解决。效果如下:
去除了空白后,发现在最后一个图片的底部也有一个相对较大的空白,如何产生的呢?为了方便观察,我们给每一个span.fix
增加一个边框,并在最后一个span.fix
的后边增加几个字母。结果如下:
从结果可以知道,最后一个span
与后面裸露文字节点的基线对齐。还记得前面说过的两个inline-block
排列错位的例子吗?这就是和那个是一样的道理。由于前面一个span
是没有inline boxes
的节点,那么它的基线就是元素底部,加上默认情况下是基线对齐,从而空白的span
将往下掉。那怎么办呢?一种方法改变基线的位置,另一种方法是改变对齐的方式。改变基线的方式就是在空白的span
里面加入内容,如空格。我们把“xxxx”挪到span
里面,结果如下:
发现此时,空白奇迹般的不见了。原因正是我们改变了原有的span
基线的位置。同时由于设置了line-height:0
,所以就对齐了。另一种方法是改变对齐的方式,我们设置为top,并去除所有的辅助线和字符,结果如下:
- 为什么是近似垂直居中
前面我们多次提到“近似垂直居中”这个词。为什么是近似,而不是绝对呢?问题还得回到这张图。
当设置元素的对齐方式为middle时,指的是:元素的垂直中心线与父级元素基线的位置往上二分之一x-height
高度所在线对齐。换句话说,就是图中的黄色线与红色字母x的中心处对齐。但是文字具有下沉特性,原本x的中心点应该与图中的白色线对齐,但是文字的偏移特性(图中为下沉特性)使字母偏移,从而导致黄色线无法绝对与白色线对齐(为了说明问题,图片特意将x下沉的幅度调大了)。这个偏移的大小与文字的大小和字体有关。当文字大小足够小时,我们可以忽略,近似的,白色线就与黄色线对齐,实现居中效果。但是文字的font-size
很大时,就不能很好的实现了。我们还是以上面的例子:
<div class="wrap" style="height:200px;line-height:200px">
<img src="../.@img/css/zhuyin.png" class="middle">x
</div>
2
3
img {
width: 100px;
}
.wrap {
background: #249ff1;
margin: 10px;
}
.middle {
vertical-align: middle;
}
2
3
4
5
6
7
8
9
10
当我们设置line-height
与height
大小一直时,实现了垂直居中的效果。我们借助画图工具往图中做一些辅助线。
结果显示,图片的中线(红色)并没有与父级元素中线(橙色)完全重合。由于字符下沉的大小与文字的大小有关系,我们把父级的font-size
设置为100px,结果如下:
此时可以明显的观察到,图片的上部空白比下部空白要大。其偏差正好是文字下沉的偏差。用图片工具做辅助线观察如下:
问题的根源找到了,那么有没有办法实现绝对居中呢?答案是有的。解决办法很明显,如果我们让父级元素的各种线重合在一起,也就是font-size
设置为0,就可以实现绝对居中了。给父级元素设置font-size:0
,结果如下:
# 五、总结
要彻底掌握line-height
和vertical-align
两个属性有很多细节需要去分析去发现,是有点难度的。但是我们如果弄清楚了常见的几个特性和行为,就能避免实践的过程中遇到的一些坑。从而提高工作效率。通过以上的一些分析,总结以下几点:
知识点总结
- 理清
line-height
与height
之前的关系; - 理清
vertical-align
不同值的表现行为; - 理解四种内联盒子的关系;
- 理解基线的定义,包括
inline-block
元素以及父级元素的基线定义; - 理解中线的定义,理清
middle
真正的表现方式; - 知道字符有下沉特性
- 理解不同值类型
line-height
的计算规则 - 综合掌握
vertical-align
和line-height
之间的关系。 - 对这篇文章提及的知识有个大概的了解《文字特性与CSS单位》