display: inline-block 什么时候不会显示间隙?
面试速答(30 秒版 TL;DR)
inline-block的“间隙”本质不是 CSS 的margin/padding,而是 HTML 源码里的空白字符(空格/换行/Tab)形成的“空白文本节点”在渲染:inline-block像文字一样排版,空白字符就会被当成一个“空格”显示出来。- 所以 不会出现间隙 只有两类情况:
- 元素之间没有可渲染的空白文本节点(标签紧挨着写,或用注释把换行吃掉等)。
- 空白文本节点的“宽度为 0”(最常见做法:父元素
font-size: 0,再给子元素恢复字体大小)。
心智模型:间隙从哪来?
inline-block 是 inline-level box,参与 行内排版(inline formatting context)。当你写:
<span class="a"></span>
<span class="b"></span>
中间那段换行在 HTML 解析后是一个 文本节点(内容是空白)。在默认 white-space: normal 下,空白会折叠成一个普通空格,于是渲染出来就像:
[inline-block A][空格][inline-block B]
什么时候不会显示间隙?(结论 + 代码)
1)标签之间没有空白字符(最“本质”的无间隙)
<span class="item">A</span><span class="item">B</span><span class="item">C</span>
适用场景:你可以接受把标签写在同一行(或经过 minify 后自然变成同一行)。
2)用注释“吃掉”换行(保留换行排版,同时不产生空白文本节点)
<span class="item">A</span><!--
--><span class="item">B</span><!--
--><span class="item">C</span>
适用场景:想保持源码格式化,但不想出现间隙。
注意:注释本身不渲染,不会贡献“空格宽度”。关键在于 不要在标签之间留下真正的空白字符。
3)空白存在,但它的宽度为 0:父元素 font-size: 0(工程最常用)
<style>
.wrap {
font-size: 0; /* 让“空白文本节点”的空格宽度变成 0 */
}
.item {
display: inline-block;
font-size: 14px; /* 记得给子元素恢复,否则文字也会变 0 */
width: 80px;
height: 32px;
line-height: 32px;
text-align: center;
background: #eee;
}
</style>
<div class="wrap">
<span class="item">A</span>
<span class="item">B</span>
<span class="item">C</span>
</div>
适用场景:需要兼容老布局、又不想改动 DOM 结构(仍用 inline-block)。
典型题 & 标准答法
Q:为什么 inline-block 之间会有 4px 左右的缝?
答:因为 inline-block 参与行内排版,标签换行/空格会变成空白文本节点,最终折叠成一个“空格”渲染出来。间隙宽度不是固定 4px,而是 一个空格的宽度,会受 font-size/font-family/letter-spacing/word-spacing 影响。
Q:什么时候不会有缝?
答:当 元素之间没有可渲染的空白文本节点(标签紧挨着写/用注释吃掉换行),或者 让空白文本节点的空格宽度为 0(常用:父元素 font-size:0,子元素恢复字体大小)。
常见追问
margin: 0能消掉吗?- 不能。这个缝来自“空格”,不是 margin。
white-space: nowrap能消掉吗?- 不能。它主要影响换行策略,不会让空格消失。
- 有没有更推荐的布局方式?
- 如果你不是被历史原因锁死在
inline-block,优先用flex/grid,它们不会受 HTML 空白字符影响。
- 如果你不是被历史原因锁死在
易错点/坑
font-size: 0会让父元素里的 所有文本节点都变成 0:必须在子元素把font-size恢复回来。- 用
letter-spacing/word-spacing或负 margin 的“对齐技巧”虽然也能掩盖空隙,但更脆弱:不同字体、缩放、组件化复用时更容易出问题。
速记要点(可背诵)
inline-block间隙 = HTML 空白字符渲染出来的“空格宽度”。- 无间隙:要么 没有空白文本节点,要么 让空格宽度为 0(
font-size:0)。