如何停止浏览器渲染inline-block元素之间的空格

8
粗略来说,我试图构建一个四列布局,这是我的HTML代码:
<div>
    <div>A column</div>
    <div>A column</div>
    <div>A column</div>
    <div>A column</div>
</div>

我有这样的CSS:

div {
    background: #ccc;
}

div div {
    background: #eee;
    display: inline-block;
    width: 25%;
}

-> 点此查看示例 <-

当在浏览器中显示时(目前仅在Chrome中测试),嵌套的div元素之间的空白符(在此示例中是由换行符引起的)被呈现出来,从而破坏了我的布局。

显然,我可以让我的嵌套div浮动...

div {
    background: #ccc;
}

div div {
    background: #eee;
    width: 25%;
    float: left;
}

-> 点我,试试看 <-

然而我的容器div会塌陷,我不想使用CSS clearfix技巧或者额外的HTML来打开它。

或者我可以修改我的HTML,将空白部分去掉...

<div><div>A column</div><div>A column</div><div>A column</div><div>A column</div></div>

但这使得它难以处理。将标签分开以使其更易读的替代方案让我感到不太舒服...

<div>
    <div>A column</
    div><div>A column</
    div><div>A column</
    div><div>A column</div>
</div>

我找到了一些资源或者方法(在SO上没找到),但是我并不喜欢这些解决方案——它们都是权宜之计,如果必须的话我会使用,但肯定有其他的办法吧?

所以我的问题是......有没有一种跨浏览器、符合w3c标准、无需使用javascript、无需hack、整洁的HTML代码,能够在使用display:inline-block时防止浏览器渲染HTML中的空格?或者有没有其他的替代方案,没有不良副作用?

编辑

假设这确实是不可能的,最好的解决方案是不需要额外的HTML标记和“灵活”的CSS。换句话说,网站管理员可以像平常一样编辑HTML而不用考虑破坏布局,CSS(无论是hack还是其他方式)都将适应网站管理员的修改,而无需自行修改。

我的“权宜之计”

好吧,看来必须得让出点什么。在我这种情况下,更重要的是拥有不需要额外标记的HTML,因此最好的解决方案是在嵌套的div中添加一个hack并将其浮动。

div div {
    float: left;
}

div::before,
div::after {
    content: "";
    display: table;
}

div::after {
    clear: both;
}

div {
    *zoom: 1;
}

这是我使用已久并希望避免的解决方法的衍生版本。这个简洁版的解决方法可以在这个网站上找到。

因此,现在标记中的每个div都已应用clearfix hack,无论是否需要。我还不知道将其应用于所有 div是否会产生任何副作用-当出现任何问题时,我期待着调试和修复;-)


1
如果你真的想要满足所有这些标准(跨浏览器、符合w3c标准、无需Javascript、无Hack、整洁的HTML、牢不可破的方式)- 不,没有。 - kleinfreund
1
提出的解决方案,就像您在http://css-tricks.com/fighting-the-space-between-inline-block-elements/所建议的一样,通过为块设置font-size:0并为元素设置所需的font-size似乎是一个很好的解决方案:没有奇怪的HTML代码等等.. 我会使用它。 - audre7
1
@audre7 你要么依赖于子div的基于像素的字体大小 - 这不太好,要么使用相对的EM单位 - 这在IE8及以下版本不支持。(在我看来,依赖于REM单位将是这两种方式中最好的选择) - kleinfreund
1
打破标签的肮脏感觉是我见过的最干净的解决方案。调整边距和字体大小可能会产生不良副作用。除了那种肮脏的感觉外,去除空格没有任何问题 ;) - xec
1
@kleinfreund - 我已经使用类似的东西很多年了 - 承认是同样技巧的老式版本。我甚至也称它为 .cf :) 这一直是我喜欢的解决方案。 - Doug
显示剩余15条评论
4个回答

7
你提供了几乎所有可能的解决方案来解决这个大布局问题。我只想指出我的首选解决方案。

将父元素的字体大小设置为0,然后使用REM重置。

如果父div中没有其他文本(而不是子div),你的代码和布局就不会有任何问题。
相对于根文档元素(即html元素),REM(相对EM)与父元素的字体大小无关。 HTML:
<div class="parent">
    <div class="child">column 1</div>
    <div class="child">column 2</div>
    <div class="child">column 3</div>
    <div class="child">column 4</div>
</div>

CSS:

html {
    font-size: 1em;
}

.parent {
    font-size: 0;
}

.child {
    display: inline-block;
    font-size: 16px; /* Add pixel-based font-size to support IE8 and below */
    font-size: 1rem; /* Don't use rem along with the font-shorthand to avoid problems in IE9/10 - see note below */
    width: 25%;
}

浏览器不支持:

  • IE8及以下版本:添加基于像素的字体大小以使其正常工作。
  • IE9/10:不支持font缩写;请改用font-size
  • (Opera Mini和iOS 3.2)

2

在使用display:inline-block时,有没有一种方法可以防止HTML空格在浏览器中呈现?

是的,有几种方法。它们都不完全符合您的“无hack”和“整洁”的标准,但它们确实有效。

  • Reformat ('minify') your code so that it doesn't have any white space between the elements.
    This is probably the most hack-free and cross-browser solution. It isn't necessarily tidy though, and it means you're fixing your layout by adjusting the HTML rather than the CSS, which isn't ideal. But it does work well. If you want to keep your code readable, you could use HTML comments so you can keep the gaps but without them being in the DOM:

       <div>block 1</div><!--
    --><div>block 2</div><!--
    --><div>block 3</div>
    

    Still not ideal, but more readable than a massive single line of code.

  • Set the font-size to zero for the container, and back to full size again for the blocks.
    This works really well. It's a pure CSS solution and easy to do. The down side is that it can be difficult to work with if you've got relative font sizes (ie setting back to 14px is fine, but setting to 1em won't work because 1em of the previous font size of zero is still zero).

  • Set a 1em negative margin to close the gap.
    This also works pretty well, but can be imprecise.

还有没有其他的替代方案可以用来替代inline-block,而且不会产生不良影响?

  • 总是可以使用float:left。但它本身也有一系列不同的问题。如果您正在使用inline-block,那么很可能是因为您不想使用浮动。

  • 使用position:absolute并手动布局。


0

你可以使用你在问题中描述的float方法,但是你没有清除浮动,这就是容器崩溃的原因。

一个好的方法是使用附加到容器元素的::after伪元素来“自动清除”:

 div:after {
    content: "";
    display: table;
    clear: both;
}

http://jsfiddle.net/s2rJW/3/


1
如果您想了解更多关于这个清除浮动方法的内容,请参考http://nicolasgallagher.com/micro-clearfix-hack/。 - kleinfreund

0

当我看到你的“解决方法”时,我在想:为什么不使用 <table>

然后我想出了这个:

div {
  background: #ccc;
  display: table;
  width: 100%;
}
div div {
  background: #eee;
  display: table-cell;
  width: 25%
}
<div>
  <div>A column</div>
  <div>A column</div>
  <div>A column</div>
  <div>A column</div>
</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接