inline-block 的空隙问题在 Flexbox 还没一统天下的那个年代,前端为了实现元素的跨行平铺(比如商品列表、九宫格图片),最常用的手段就是给盒子加上 display: inline-block。
然而,几乎每个前端新人都被它折磨过:明明计算好了百分比宽度(比如各自 50%),只要并排放两个方块,第二个方块必定因为“挤不下”而掉到下一行去。打开开发者工具一查,发现这俩紧挨着的方块之间,竟然莫名其妙地隔着一条几像素宽的空白缝隙!
这究竟是浏览器的 bug,还是隐藏的设计逻辑?
这不是 bug,这是浏览器对待“文本”的底层规则。
inline-block 翻译过来叫“行内块”。一旦元素具备了“行内(inline)”的特性,浏览器就不再把它单纯当作一块一块的面包,而是把它当成了文本中的一个巨大的字母。
在书写 HTML 时,为了代码美观,我们通常会打回车、按 Tab 键进行换行和缩进:
在 HTML 的解析规则中,标签之间的回车、换行、连串空格,都会被合并解析为一个空白字符(Space)。 于是,既然你的包裹元素是“行内”的,两个元素之间的那个看不见的换行符,自然就被渲染成了类似英文单词之间的一个空格。这个空格占据了大概 3~4px(取决于父元素的字体大小),最终导致了整体宽度的溢出。
既然查明了真凶是“HTML里不起眼的换行符变成的空格”,我们要剿灭它就有以下几套方案。
既然是换行符惹的祸,那我干脆不换行了。
做法(任选一种):
<div>box1</div><div>box2</div>(缺点是牺牲了代码可读性)缺陷:改起代码来极其别扭,而且当你使用 React/Vue 等框架通过数组 map 渲染列表时,这种方法根本无能为力。
font-size: 0 (最经典、最稳定)既然缝隙是因为它被当成了文本(空格),那么我们直接让这里的文本没有大小不就行了?
做法:给父容器设置字体大小为 0,然后在子元素里重新把所需的字体大小补回来。
推荐度:⭐⭐⭐⭐(如果必须用 inline-block,这是首选方案)
margin既然缝隙多占了几个像素,我就用负外边距把它扯回来。
缺陷:极其不稳定。不同的字体家族(font-family)、不同的父级字号、不同浏览器的渲染机制,都会导致这个“空格尺寸”发生变化。你在这个页面写 -4px 正好,换个页面或者换个系统设备可能就又错位了。
inline-block,拥抱新时代与其绞尽脑汁去对付这些怪异的“文字特性”,为什么不彻底抛弃它呢?
我们真正想要的是布局控制器,而不是排版控制器。直接切换到现代 CSS 的基石:Flex 或者 Grid。
推荐度:⭐⭐⭐⭐⭐(能用 Flex 绝对不碰 inline-block)
Q:为什么 inline-block 的元素之间会有空隙?怎么消除?
回答思路:
inline-block 保留了类似文字的“行内”特性。<!-- -->),但表示这种方法在现代使用 React/Vue 通过数据渲染 DOM 时不现实。font-size: 0 抹平空格大小,记得要在子元素把 font-size 重新加上。display: flex 或 grid 是最佳选择,干净又可控。