yanni4night

挑战移除 inline-block 元素之间的空白

yanni4night · 2016-08-09翻译 · 923阅读 原文链接

最近我在 Twitter 上遇到了好几次这个问题,然后又是在 Dabblet 上的一个有趣的例子,所以我想这个问题很重要,值得记录下来。

事情是这样的,一系列被正常格式化的 inline-block 元素之间会存在空白。

也就是说:

<nav>
  <a href="#">One</a>
  <a href="#">Two</a>
  <a href="#">Three</a>
</nav>
nav a {
  display: inline-block;
  padding: 5px;
  background: red;
}

渲染结果是这样的:

这些空白间隙通常都是不受欢迎的。

我们一般想要的效果是元素一个紧挨着前一个。在导航栏这个例子上,这意味着可以避免在导航按钮之间存在有不可点击小间隙的尴尬。

这不是一个 “bug”(至少我不这么想)。它只是把元素放在同一行进行排列所导致的。你会想要在键入的单词之间留有空白对吧?这些块元素之间的空白就像单词之间的空格一样。这并不是说,现在的规范不能被修订来说明 inline-block 元素之间的空白应该什么也不是的道理,但我相当确定这是之前不太可能遭遇过的麻烦。

下面是一些能够移除中间间隙,让 inline-block 元素紧密排列的方法。

移除空白

出现空白的原因是因为在元素之间有空白字符(注意一个换行和一些 tab 都算做一个空白)。精简 HTML 标签会解决这个问题,或者使用下面这些技巧:

<ul>
  <li>
   one</li><li>
   two</li><li>
   three</li>
</ul>

或者

<ul>
  <li>one</li
  ><li>two</li
  ><li>three</li>
</ul>

或者使用注释...

<ul>
  <li>one</li><!--
  --><li>two</li><!--
  --><li>three</li>
&$L̪ԌE$L̪Ԍ>这些做法都是相当地不雅,但确实达到了目的。

负外边距

你可以把元素用 -4px 的外边距(取决于父元素的字体大小)挪到正确的位置。显然,这在老版本的 IE 浏览器(6和7)下会有问题,不过如果你不关心这些版本就没有关系,况且这可以保持你的代码干净。

nav a {
  display: inline-block;
  margin-right: -4px;
}

省略标签闭合

HTML5 并不关心是否存在标签闭合。不过你得承认,缺少标签闭合看上会去会很奇怪。

<ul>
  <li>one
  <li>two
  <li>three
</ul>

设置字体大小为0

具有 0 值 font-size 的空白自然是 ... 0 宽度的。

nav {
  font-size: 0;
}
nav a {
  font-size: 16px;
}

Matt Stow 报告说使用 font-size: 0; 这种技术在 Android 上会有问题。他提到:Android 4.3 之前的版本根本就不会移除空白,而 4.3 则会有在最后一个元素上随机留有一个微小的空白的 bug。参见实验

此外需要注意,如果你使用em单位设置字体,0 值的字体尺寸就会有问题,因为 em 的级联特性会让子元素也具有 0 值的字体尺寸。rem 单位就没有关系,包括其它的非级联的 font-size 的值都会规避掉这个问题。

还有另一个奇怪的问题!Doug Stewart 为我展示了如果你将 @font-face 和该技术一同使用,字体就会在 Safari 5.0.x 版本下丢失反锯齿特性。(测试) (截图).

使用浮动布局

也许这些元素不一定非要是 inline-block 的,也许它们可以一个挨着一个进行浮动。这允许你设置宽高、内边距等属性。你不能以把 inline-block 的父元素设置 text-align: center; 的方式来居中它们。哦...其实也可以,但它会表现得很怪异

使用 flexbox 布局

如果浏览器支持程度允许的话,并且除了 inline-block 之外也需要居中布局,你可以使用 flexbox。它们不是可以相互替代的布局模型,但可以满足你的需求。

参考

示例 CodePen:

相关文章