空白节点
刀刀
1/3/2025
0 字
0 分钟
场景重现
在介绍空白节点之前,首先看一个案例。代码如下:
<style>
* {
margin: 0;
padding: 0;
}
div {
background-color: red;
}
</style>
<body>
<div>
<span></span>
</div>
</body>
此时打开页面是没有背景色的,因为没有内容把他撑开。如果给 span
添加内容,则会因为有内容高度把它撑开,显示红色的背景色。
现在给 span
修改为行内块元素,代码如下:
span {
display: inline-block;
}
此时页面显示了红色空白,效果如下:
就像一个空白的幽灵节点一样,把父盒子撑开。
前置知识
首先我们需要了解一个概念,叫做基线,在所有内联相关模型中,凡是涉及到垂直方向的排版或者对齐的,都离不开最最基本的基线(base-line),那么基线是怎么定义的呢?在维基百科中有这么一个示意图:
根据图片中标示,字母 x 的下边缘(线)就是基线。
在 CSS 中有两个重要属性,line-height
和 vertical-align
都与基线有关,line-height
行高的定义就是两个基线之间的距离,vertical-align
的默认值就 baseline
,也就是基线对齐。对于内联元素,我们要认识到,虽然 vertical-align
与 line-height
看不见,但实际上到处都是!
那么标签元素的基线如何确认呢?在 CSS2 的可视化格式模型文档中有这样一段话:
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
元素,如果里面没有 inline
内联元素,或者 overflow
不是 visible
,则该元素的基线就是其 margin
底边缘,否则,其基线就是元素里面最后一行内联元素的基线。
因此,当 <span>
中空白并且为 inline box
的时候,div
中似乎依然有一个和类似 x 字符的空白节点,来撑起 line box
的高度。为了帮助我们理解,在这里我们可以把字符 x 看作为“幽灵空白节点”具像,它不占任何宽度,看不见也无法通过任何方式获取,但又似乎真实存在,它的大小会受 font-size
的影响。
认识“幽灵空白节点”
在 HTML5 规范中有这样一句话:
"Each line box starts with a zero-width inline box with the element's font and line height properties. We call that imaginary box a 'strut'."
每个行框盒子都以一个具有元素的字体和行高属性的零宽度行内框开始。我们称这个假想的盒子为"支柱"。
在HTML5 文档声明中,内联元素的所有解析和渲染表现就如同每个行框盒子的前面有一个“空白节点”一样。这个“空白节点”永远透明,不占据任何宽度,看不见也无法通过脚本获取,就好像幽灵一样,但又确确实实地存在,表现如同文本节点一样,因此,在张鑫旭大佬的《CSS 世界》一书中根据特点,将其称之为“幽灵空白节点”,也就是官方规范中的 “strut
”。
消除“幽灵空白节点”的影响
终于找到并认识了“幽灵空白节点”,那么对于这种无法获取却又真实影响我们样式的“节点”,我们应该如何消除它带来的影响?
- 1、让
vertical-align
失效:vertical-align
属性对于块级元素是无感的,因此我们只需要为元素设置dispaly
为block
即可; - 2、修改
vertical-align
属性值:修改其默认值baseline
值为其他属性值,使其不再相对基线对齐; - 3、修改
line-height
的值:上面我们说过line-height
的定义是两基线之间的距离,因此在上面例子中,图片下面的空隙,实际上是“幽灵空白节点”计算后的行高值和基线的距离,因此,只要line-height
足够小,便可以消除图片下面的空隙。(注意这里是要在div
上设置line-heght
,然后让div
的inline boxes
继承line-height
属性