引言
之前一直不是很明确CSS行内元素布局的具体规则,最近看《CSS权威指南》这本书,总算对这部分内容有了系统的理解,故将其中最重要的部分结合我自己的理解整理出来,并做了一些演示。
一、行内元素的结构
首先考虑最简单的一种情形,一个块元素包裹一个行内非替换元素。p标签直接包裹文本即满足这种情形,此时p标签内的文本可称为匿名文本,其显示效果与p标签包裹一个span标签等价。

在这样的一个p标签内,包含了如下几个区域(非替换元素的情形):
关于最小行框,这里有个例子:

此时p标签内仍然只有一个行内元素,但行框的高度与行内框的高度却不相等(确切的讲,此时行框高度30px,行内框高度21px),这就是行框最小高度的影响。将line-height设置为0可以消除这一影响。如果line-height的属性被设置为一个倍数(浏览器的默认属性就是这么做的),把font-size设置为0也一样能解决问题。(个人更喜欢后一种做法,因为这种情况下子元素的字体大小往往会被重新设置,而行高属性能被正常继承不需要额外编写样式。)
注:《CSS权威指南》中没有具体解释这种最小行框高度。按我的理解,其意义在于,文档在渲染父元素某一行的时候,就可以确定了这一行的基线(见下文)位置,接下来只需要将行内元素的行内框一个个摆放在基线上,根据vertical-align属性在垂直方向上确定位置后,根据需要调整行框的高度,就行了。这与CSS渲染页面时自上而下的顺序是一致的。此外vertical-align属性对齐时,部分属性的对齐位置也是来自于这个最小行框的(确切的说应该是父元素的字体大小,见下文)。
二、基线与对齐
基线是文本中的概念,这条虚拟的线与小写英文字母x的下缘对齐,如图所示。



值得注意的是对30px的行内元素设置不同行高的情况,这是因为在各个行内框基线对齐之后,行框要保证包裹一行内所有的行内框,因此其高度发生了变化。
vertical-align属性还可以设置为:
总结下来,vertical-align属性最大的问题在于,在某些情况下,兄弟元素的高度会影响布局,不过在明白其原理之后,就能合理的利用或规避这一点了。
三、替换元素的情况
最典型的的非替换元素行内布局时,替换元素与非替换元素的区别主要有三点:
了解了这几点差异后,替换元素的vertical-align属性就很好理解了。以下是最简单的例子,图片的下沿落在父元素文本的基线上。

可以发现图片的下方会有一定空白区域,即使图片前的文本不存在时,这一空白也一样存在,这就是父元素最小行框的影响。一直以来的解决办法是使父元素的line-height的计算值为0。研究过vertical-align属性后,发现一种新思路:将img的vertical-align属性设置为非基于基线定位的属性,如middle,因为此时行框高度即等于图片高度。
注:对行内非替换元素设置宽度也是不会生效的,不过对其设置上下边框和内边距虽然不会影响行内框的高度,却能影响背景区域的大小。
四、inline-block行内块元素
行内块元素的行为本质上与替换元素是等价的,这里就不过多解释了。
网友评论