Inline 与 inline-block · 拆解
为什么 inline-block 的 margin-bottom: -20px 反而把元素往下推; 为什么 <a> 里放一个 <img> 后高度多出几像素;为什么两个 inline-block 之间总有一条用 margin 消不掉的窄缝——这些反直觉现象背后是同一套机制: Inline Formatting Context (IFC) 里,行内框 inline box 按 vertical-align 把自己排进行框 line box,而默认的对齐线是 baseline。
一条主线讲清:先分清 line box 与 inline box 两个概念,看清行框高度由谁决定; 再讲清 baseline 与 vertical-align(尤其 inline-block 的 baseline 位置); 然后分析三道经典问题——负 margin 下移、img 撑高、input 与 label 错位(后两道同属「替换元素 baseline 落点」);随后说明 inline-block 间隙的来历,以及 inline / inline-block / block 三者行为对照 + 实战修法;另有一页工程配方——图标如何对齐文本(cap 单位 / ZWSP strut / 奇偶 1px);末页延伸到规范前沿——基线从哪一行来(baseline-source 与 SVG 的 dominant-baseline / alignment-baseline)。 每页都可拖滑块 / 切换开关,叠加层用真实 getBoundingClientRect() 把对齐线画出来。 前置知识:本系列默认 content-area / 行框「已经存在」,它们如何从字体度量算出, 可先看 font-features · 字体度量。
取材自知乎多篇经典解答:负 margin 下移(貘吃馍香)、img 撑高(Geeker)、input 与 label 错位(貘吃馍香)、 vertical-align:top 图解(貘吃馍香)、baseline 规则的历史由来(贺师俊),并以 CSS 2.1 §9.4.2 / §10.8、 MDN IFC 与 w3help RD1016 文档校准。
行框 line box vs 行内框 inline box
行框由这一行的各行内框与 strut 共同撑起;leading 是 line-height 减去内容区高度后上下等分的部分,可为负。
baseline 与 vertical-align:对齐线在哪
vertical-align 的各取值分别对齐到什么;inline-block 的 baseline 取末行,没有 in-flow 行或 overflow 非 visible 时改用下外边距边。
负 margin-bottom 为什么把元素「往下推」
负 margin 不改变行框高度,溢出的部分直接压在下一行内容上——因为行框之间不会为它让位。
替换元素的 baseline:img 撑高 vs input 错位
img 的 baseline 是下外边距边,表单控件的 baseline 藏在盒内且各类控件并不一致;图底那条缝即由此而来。
inline-block 之间的空白间隙
inline-block 之间的间隙来自源码换行被折叠成的那个空白字符,约 0.26 em;四种消除办法各有代价。
inline / inline-block / block 对照 + 修法总结
inline、inline-block 与 block 三者在宽高、外边距与内边距上的响应差异,以及各自的适用场合。
图标如何对齐文本:cap 单位与 ZWSP strut
图标与文字的光学中线对齐:cap 单位与 ZWSP strut 两种做法,以及子像素取整带来的一像素偏差。
基线从哪一行来:baseline-source 与 SVG 基线属性
baseline-source 决定多行盒对外用首行还是末行的基线;没有 in-flow 行时仍回落到下外边距边。
相关链接
- inline-block 元素设置 margin-bottom 为负值后为什么会下移? zhihu.com · 貘吃馍香 负 margin 谜题出处。从 IFC / 行框高度的角度解释负 margin-bottom 与负 margin-top 的视觉效果。
- 为什么 a 标签中使用 img 后的高度多了几个像素? zhihu.com · Geeker img 撑高谜题出处。匿名行级盒子的 line-height + baseline 对齐把 a 撑高,给出三种根治办法。
- 设为 inline-block 的标签和 input 并排放置为何会错位? zhihu.com · 貘吃馍香 input 错位谜题出处。默认 baseline 对齐,而 input 这种替换元素的 baseline 并不在元素底部 → 和 inline-block 标签高低错位。
-
CSS 2.1 §10.8 · vertical-align 与替换元素的 baseline
w3.org
input 错位谜题的规范级依据:
baseline把盒子的基线对到父级基线上,而无基线的行内替换元素取其下外边距边——错位正由此而来。 - 关于 vertical-align: top 问题? zhihu.com · 貘吃馍香 图解匿名行内框继承 line-height、leading / half-leading、混合行高下 baseline 对齐与 vertical-align:top 的排布(02 页 worked example 蓝本)。
-
图标如何对齐文本
zhuanlan.zhihu.com · 长天之云
07 页出处。从字体度量(cap-line / x-height)讲图标对齐文本:近似对齐用
cap单位偏移,精确对齐用 ZWSP 造局部 strut(inline-flex / inline-block hack),并列出 iconSize/fontSize/lineHeight 奇偶导致的 1px 误差。 - CSS 2.1 中为何规定行内块 overflow 非 visible 时基线是底部外边界? zhihu.com · 贺师俊 解释这条 baseline 规则的历史由来:inline-block 是 CSS2 后加,有滚动时定不了末行→只能取盒边(类比 iframe);首行对齐会与 CSS1 图片对齐不一致;CSS Inline L3 用 inline-box-align 重定义。
- Inline formatting context · MDN developer.mozilla.org IFC 中 line box / inline box 的排布规则、line-height 与 vertical-align 如何决定行框高度。
- CSS 2.2 §9.4.2 Inline formatting contexts w3.org IFC 的规范定义本身:line box / inline box 怎么排、vertical-align 决定矮盒的垂直对齐、行框过窄时 inline box 如何拆到多行(断点处 margin/border/padding 不显示)、以及空 line box 视为零高/不存在。整个系列的规范总出处。
- CSS 2.1 §10.8 Line height calculations w3.org 规范原文:strut、leading、inline-block 的 baseline 取值规则(空盒子 / overflow≠visible → bottom margin edge)。
-
CSS Inline Layout Module Level 3 · baseline-source
drafts.csswg.org · CSSWG
08 页主角的规范本体:在 L3 里
baseline-source(auto / first / last)与alignment-baseline、baseline-shift一起,把vertical-align重定义为这三者的 shorthand。 - baseline-source · MDN developer.mozilla.org 08 页主角:显式指定多行 inline-level 盒拿首行还是末行 baseline 对外(auto / first / last);auto 的默认即「inline-block 取末行、其余取首行」。
- Can I use · baseline-source caniuse.com baseline-source 的实时浏览器支持矩阵:Chrome/Edge 111+、Firefox 115+ 已支持,Safari 暂未实现。
- dominant-baseline · MDN developer.mozilla.org SVG 文本的「主基线」选择:alphabetic / central / hanging / middle / text-top 等。08 页 SVG 基线两小节的参照文档(同页另见 alignment-baseline)。
- vertical-align · MDN developer.mozilla.org baseline / middle / text-top / text-bottom / top / bottom 各取值的精确含义与适用对象(只作用于 inline 与 table-cell)。
- Deep dive CSS: font metrics, line-height and vertical-align iamvdo.me · Vincent De Oliveira 本系列主题的经典长文:content-area、leading 上下半分、line-height:normal、vertical-align 的常见误用,系统讲解 —— 和本系列各页正好对应。(content-area / line-height:normal 怎么从字体度量算出,见下面那条交叉链接。)
- 姊妹页:字体度量——content-area 从哪来 playground · font-features 本系列假设 content-area / 行框「已经存在」并讲它们怎么对齐;那页用 Canvas 实测把 em-square / ascender / descender → content-area、line-height:normal 的来历画出来,正好接在这之前。