CSS 与布局 / Inline 与 inline-block · 拆解 / 行框 line box vs 行内框 inline box 待审核 1 / 8
concept · line box

行框 line box vs 行内框 inline box

本系列分析的所有现象都建立在这对概念上,先分清:一段 inline 内容在排版时,每个 inline-level 的东西(一截文字、一个 <img>、一个 inline-block)各自是一个 行内框 inline box;浏览器把同一行里的这些 inline box 收拢进一个 行框 line box行框的高度,由这一行里所有行内框按 vertical-align 对齐后「最高顶边到最低底边」的距离决定——不是由某一个盒子单独决定。

**关键:**哪怕一行里只有文字,也有一个看不见的 strut(支柱)——一个高度等于 line-height 的零宽 inline box,默认就把行框撑到至少 line-height 高。这就是为什么「空的一行也有高度」。

但「彻底空」的行不算:规范(CSS 2.2 §9.4.2)的原话是——一个 line box 若既没文字、没保留的空白、没有带非零 margin / border / padding 的 inline、也没有其他 in-flow 内容(图片、inline-block、inline-table 等),且不以保留的换行结尾,就被当作零高 line box,而且「视为不存在」。要留意「空格」并不算数——普通空格在空白处理阶段被折叠删除,实测 <div style="font:16px/2 Arial"> </div> 高度为 0,换成 &nbsp; 或加 white-space: pre 才是 32px;一个空的 inline-block 同样能让行框存在(实测 32px,Chrome 151,核对于 2026-08)。行框存在与否的这条规则,与 inline-block 间隙(空格 = 内容 → 占一格)和 img 撑高(strut 的 descent)的底层依据。

1 · 动手:把行框撑高的是谁

下面一行里有一段锚文本(带 strut)和两个 inline-block 盒子。两个盒子的高度可调,蓝色实线标出的 line box 上下边界:它永远贴着当前最高的那个,高度由最高者决定。把两个盒子都调矮于文字行高时,撑住行框的就轮到那段文字的 strut 了。

图 1-1 · 一行锚文本与两个 inline-block。可调盒子高度,蓝色实线标出行框、虚线标出各行内框。

2 · 所以「行框高度」到底怎么算

  1. 先把这一行的每个 inline box 量出来:文字用它的 line-height,替换元素 / inline-block 用它的外边距框 margin box 高度。
  2. 按各自的 vertical-align 把它们在垂直方向对齐(默认 baseline,详见 02 · baseline 与 vertical-align)。
  3. 对齐之后,取所有框里最高的顶边最低的底边,两者的距离 = 这个 line box 的高度。
  4. 多行内容就是一摞 line box,行框之间从不重叠——这条性质是负 margin 谜题的最后一块拼图。

注意区分:line-height 设在文字那个 inline box 上;而一个高 200pxinline-block 不管 line-height 多少,都会用它整个 margin box 去撑行框。line box 是「容器行」,inline box 是行里的成员——两者不是同一个东西。

3 · 补两个概念:匿名行内框 与 leading

本系列其余页面会反复用到,此处先说明:

  • 匿名行内框 anonymous inline box:直接写在容器里、没被任何标签包住的裸文字,也会被自动装进一个(匿名的)行内框。像 <div>one two <span>x</span> 三 四</div> 会被切成三段行内框:匿名「one two」+ 具名 span + 匿名「三 四」。匿名框没法直接写样式,它的 font-size / line-height从父容器继承——所以「明明没给文字设行高,它却有高度」就是继承来的。
  • leading / half-leading(行距 / 半行距):leading 是 line-height 减去内容区高度(字体的 ascent 加 descent)后剩下的部分,规范写作 L=line-heightADL = \text{line-height} - AD——注意减的是内容区而非 font-size:Arial 在 16px 下内容区约 18px(实测 line-height: normal 为 18px),所以 line-height: 16px 时 leading 已是负数,内容区反而溢出行内框。这部分被平均分成两半加在内容区上下(half-leading),所以内容区在行内框里上下等分——这也是为什么纯文字行的高度正好是 line-height,而文字像是浮在行中间。

把这两条接上前文:一行里既有继承了 line-height 的匿名文字框,又有显式设了大 line-height 或大高度的具名框 / inline-block 时,谁高谁定行框高度,其余的按 vertical-align 在里面确定自己的位置。02 · baseline 与 vertical-align 会用一个混合行高的例子(vertical-align: top)把这套规则连成一张图。