行盒(line box)垂直方向的属性详解:从font-size、line-height到vertical-align
视觉格式化模型
在一个文档中,每个元素都被表示为0、1或多个矩形的盒子。确定这些盒子的尺寸, 属性 --- 像它的颜色,背景,边框方面 --- 和位置是渲染引擎的目标。①
在CSS中,使用标准盒模型描述这些矩形盒子中的每一个。这个模型描述了元素所占空间的内容。每个盒子有四个边:外边距边, 边框边, 内填充边 与 内容边。①
盒的种类又分为:块级盒和行内级盒。如下②
一些附加概念:
- 块容器盒:直接包含的全部是块级盒的盒子称为块容器盒,它本身可能不是块级盒,比如非替换行内块及非替换表格单元格,不是块级盒。
- 块盒:同时是块容器盒的块级盒称为块盒。
- 匿名块盒:一个块容器盒内如果同时有块级盒和行内级盒,那么会自动创建匿名块盒来包含行内级盒。
- 行内盒:生成行内格式化上下文的行内级盒称为行内盒。
- 原子行内级盒:对于display为inline-block/inline-table的盒子,称为原子行内级盒,因为原子行内级盒就像一个原子一样,不能拆分成多个(盒),因为不能换行。
- 匿名行内盒:类似于匿名块盒,CSS引擎有时候有必要生成匿名行内盒。常见的例子是块级盒直接包含文本,那么这些文本将包含在匿名行内盒中。(空白如果使用white-space去掉,则不会生成匿名行内盒)
- 行盒:由行内格式化上下文产生的盒称为行盒,用于表示一行。行盒从包含块的一边排版到另一边。当有浮动时,行盒从左浮动的最右边排到右浮动的最左边。
行盒
由于我们今天讨论的是内联元素垂直方向上发生的事,所以我们直接讨论一个行盒的内部行为即可,一个行盒可以由块级盒产生,也可以由行内级盒产生,它描述了一行行内元素的渲染方式。一个行盒的内部组成是这样的:(不太会用PS,做的丑了一点,将就看一下……)
顶线(top line)
在印刷字体中,顶线的定义是小写字母k或h的最高点对应的线③。不过我们在实际使用中发现小写字母k或h的最高点并没有到达顶线的位置,最高点的位置还与所用的字体有关,一般我们的网页中所用的字体,顶线的位置都会比k或h的最高点更高一些。像上图所示的那样。所以把顶线理解成文本的最高点对应的线比较好。
底线(bottom line)
底线的定义是小写字母y的最低点对应的线,如上图所示。
中线(middle line)
中线的定义是小写字母x的交叉点对应的线,注意,这并不是真正的内容区中线。
基线(base line)
基线的定义是小写字母x的最低点对应的线。这条线也是 vertical-align 默认采用的垂直对齐方式,即baseline。
内容区
从顶线到底线之间即为内容区。
行间距
行间距可以认为是line-height与内容区高度之间的差值,准确地描述是上一行的底线到下一行的顶线之间的距离,即可以认为是非内容区域的高度。
行内框
对非替换行内级元素来说,行内框高度就是它本身的line-height,对于替换行内级元素来说,行内框高度是它的实际高度。
行高
上一行基线到下一行基线的高度,可以认为是line-height(毕竟人家中文名字就叫行高啊>_<|||)。
行框
本行盒内所有行内框里最大的一个决定了行框,相当于最大的一个行内框把行盒撑开了。比如行盒内有一个有内容的span的line-height大于行盒本身的line-height,那么行盒本身会被撑大。
font-size
font-size是一个我们经常使用的属性,有时查文档,会看到这个的定义是字体的大小,这不成了翻译了嘛,其实font-size的精确定义是,大写字母S的最高线到小写字母y的最低线的距离。④
line-height
一个行盒的基本表现,除了由font-size决定,还由line-height决定,正如上面说的,行高决定了上下两行之间基线的垂直距离,即是一行的高度。我们从上面的说明图片来看,line-height即是绿色区域加文字内容区域的高度。当设置了font-size属性后,再根据字体,就决定了文字内容区的高度,line-height决定了行高,line-height减去内容区高度后,剩余的高度即是行间距,这个行间距被平均地分到内容区的上下两侧。
对于块级元素来说,line-height指定了其内部行内盒的最小高度。对于非替换行内元素来说,line-height用于计算其行盒的高度,对于替换内联元素来说,line-height对它没有影响。
vertical-align
vertical-align属性定义了行内级盒的垂直对齐方式。注意是行内级盒,这样描述比较精确,因为行内级盒包括行内盒、原子行内级盒还有匿名行内盒,这些盒都可以用vertical-align控制垂直对齐,块级盒的vertical-align属性是无效的。不过顾名思义,对齐,至少要有两个东西才存在对齐一说吧,所以到底是什么与什么对齐呢?更加精确的描述,vertical-align定义了行内级盒相对于父元素行盒的垂直对齐方式。(行盒的概念在上方插图中有,它是由行内格式化上下文产生的盒)
vertical-align可以取的属性值⑤:
baseline
默认值,元素基线与父元素基线垂直对齐,对于替换行内元素来说,由于没有明确定义它的基线,所以各个浏览器下的表现可能不一样。
sub
元素基线与父元素的下标的基线对齐。
super
元素基线与父元素的上标的基线对齐。
text-top
元素顶端与父元素文字内容区的顶端对齐。
text-bottom
元素底端与父元素文字内容区的底端对齐。
middle
元素中线与父元素的小写x中线对齐。
top
元素的顶端与父元素的顶端对齐。
bottom
元素的底端与父元素的底端对齐。
< length>
元素基线超过父元素基线的指定高度,可以取负值。
< percentage>
元素基线超过父元素基线的百分比高度,这个百分比是对于元素自身的line-height来说的。(注意line-height是可以继承的,如果子元素没有特意设置line-height,那么将继承父元素的line-height)
实例面板
参考张鑫旭大神的作品制作了一个实验面板,用这个实验面板控制属性,配合文中的讲解,相信就能更方便地理解文中的概念啦!
vertical-align 实验面板
引用/参考资料
①: MDN - 盒子模型
②: MDN - 视觉格式化模型
③: WebpageFX - The Basics of Typography
④: PEARSONIFIED - Secret Symphony: The Ultimate Guide to Readable Web Typography
⑤: MDN - vertical-align
⑥:张鑫旭博客 - 我对css-vertical-align的一些理解与认识(一)
⑦: segmentfault - 想要清晰的明白(二)CSS 盒模型Block box与Line box