您如何防止浮动元素的父项崩溃?

尽管<div>的元素通常会增长以适合其内容,但是使用float属性可能会给 CSS 新手带来一个惊人的问题: 如果 float 元素具有非 float 父元素,则父元素将折叠。

例如:

<div>
  <div style="float: left;">Div 1</div>
  <div style="float: left;">Div 2</div>
</div>

在此示例中,父 div 不会扩展为包含其浮动的子级 - 看起来具有height: 0

你怎么解决这个问题?

我想在这里创建一个详尽的解决方案列表。如果您知道跨浏览器的兼容性问题,请指出。

解决方案 1

浮动父母。

<div style="float: left;">
  <div style="float: left;">Div 1</div>
  <div style="float: left;">Div 2</div>
</div>

优点 :语义代码。
缺点 :您可能并不总是希望父母浮动。即使您这样做,您是否也会浮动父母的父母,依此类推?您必须浮动每个祖先元素吗?

解决方案 2

给父母明确的身高。

<div style="height: 300px;">
  <div style="float: left;">Div 1</div>
  <div style="float: left;">Div 2</div>
</div>

优点 :语义代码。
缺点 :不灵活 - 如果内容更改或调整浏览器大小,布局将中断。

解决方案 3

在父元素内附加一个 “spacer” 元素,如下所示:

<div>
  <div style="float: left;">Div 1</div>
  <div style="float: left;">Div 2</div>
  <div class="spacer" style="clear: both;"></div>
</div>

优点 :直接编写代码。
缺点 :没有语义; spacer div 仅作为版式 hack 存在。

解决方案 4

将父级设置为overflow: auto

<div style="overflow: auto;">
  <div style="float: left;">Div 1</div>
  <div style="float: left;">Div 2</div>
</div>

优点 :不需要额外的 div。
缺点 :好像是 hack - 这不是overflow属性的既定目的。

注释?还有其他建议吗?

答案

解决方案 1:

最可靠和毫不干扰的方法似乎是这样的:

演示: http//jsfiddle.net/SO_AMK/wXaEH/

HTML:

<div class="clearfix">
    <div style="float: left;">Div 1</div>
    <div style="float: left;">Div 2</div>
</div>​

CSS:

.clearfix::after { 
   content: " ";
   display: block; 
   height: 0; 
   clear: both;
}

有了一点 CSS 定位,您甚至不需要向父DIV添加一个类。

此解决方案向后兼容 IE8,因此您无需担心较旧的浏览器出现故障。

解决方案 2:

已建议对解决方案 1 进行以下修改:

演示: http//jsfiddle.net/wXaEH/162/

HTML:

<div class="clearfix">
    <div style="float: left;">Div 1</div>
    <div style="float: left;">Div 2</div>
</div>​

CSS:

.clearfix::after { 
   content: " ";
   display: block; 
   height: 0; 
   clear: both;
   *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML += '<div class="ie7-clear"></div>' );
}

.ie7-clear {
    display: block;
    clear: both;
}

此解决方案似乎向后兼容 IE5.5,但未经测试。

解决方案 3:

也可以设置display: inline-block; width: 100%;模拟正常的块元素而不塌陷。

演示: http//jsfiddle.net/SO_AMK/ae5ey/

CSS:

.clearfix {
    display: inline-block;
    width: 100%;
}

此解决方案应向后兼容 IE5.5,但仅在 IE6 中进行了测试。

我通常使用overflow: auto把戏;虽然这不是严格来说,溢出的用途,它有点相关 - 足以令它容易记住,一定。 float: left的含义float: left本身已针对各种用途进行了扩展,比本例中的 IMO 溢出要重要得多。

与其将overflow:auto置于父级,不如将overflow:hidden

我为任何网页编写的第一个 CSS 始终是:

div {
  overflow:hidden;
}

那我就不用担心了。

当浮动元素位于容器框中时,就会发生问题,该元素不会自动将容器的高度调整为浮动元素。浮动元素时,其父元素不再包含该元素,因为从流中删除了该浮动元素。您可以使用 2 种方法来修复它:

  • { clear: both; }
  • clearfix

了解发生了什么之后,请使用以下方法 “清除” 它。

.clearfix:after {
    content: ".";
    display: block;
    clear: both;
    visibility: hidden;
    line-height: 0;
    height: 0;
}

.clearfix {
    display: inline-block;
}

html[xmlns] .clearfix {
    display: block;
}

* html .clearfix {
    height: 1%;
}

示范:)

该 clearfix 有多个版本,主要作者是Nicolas GallagherThierry Koblentz

如果您想支持较旧的浏览器,最好使用以下 clearfix:

.clearfix:before, .clearfix:after {
    content: "";
    display: table;
}

.clearfix:after {
    clear: both;
}

.clearfix {
    *zoom: 1;
}

在 SCSS 中,您应该使用以下技术:

%clearfix {
  &:before, &:after {
    content:" ";
    display:table;
  }

  &:after {
    clear:both;
  }

  & {
    *zoom:1;
  }
}

#clearfixedelement {
    @extend %clearfix;
}

如果您不关心对旧版浏览器的支持,则可以使用以下较短的版本:

.clearfix:after {
    content:"";
    display:table;
    clear:both;
}

尽管代码不是完全语义化的,但我认为在每个包含浮点数的容器的底部都放一个我所谓的 “清除 div” 更为简单。实际上,我在每个项目的重置块中都包含以下样式规则:

.clear 
{
   clear: both;
}

如果您要为 IE6 设置样式(上帝帮助您),则可能还希望将此规则的行高和高度设为 0px。

理想的解决方案是对列使用inline-block而不是浮动。我认为,如果您遵循(a)仅将inline-block应用于通常内联的元素(例如span ),则浏览器支持会很好。 (b)为 Firefox 添加-moz-inline-box

还要在 FF2 中检查您的页面,因为在嵌套某些元素时我遇到了很多问题(令人惊讶的是,这是 IE 性能比 FF 好得多的一种情况)。

奇怪的是,还没有人给出一个完整的答案,嗯,好吧。

解决方案一: 明确:两者

添加样式元素 clear:both; 在其上将清除经过该点的浮动对象,并阻止该元素的父对象崩溃。 http://jsfiddle.net/TVD2X/1/

优点:允许您清除元素,并且您在下面添加的元素将不受上方浮动元素和有效 CSS 的影响。

缺点:需要使用另一个标签来清除浮标,浮标。

注意:要回退到 IE6 并使其在节制的父母(即输入元素)上工作,您将无法使用:after。

解决方法二: 显示:表格

添加显示:表;给父母,让它从花车上耸了出来,并以正确的高度显示。 http://jsfiddle.net/h9GAZ/1/

优点:没有额外的标记,而且整洁了很多。在 IE6 + 中可用

缺点:要求使用无效的 CSS,以确保 IE6 和 7 中的所有内容都能正常运行。

注意:IE6 和 7 宽度自动用于防止宽度为 100%+ 填充,而在较新的浏览器中则不是这种情况。

关于其他 “解决方案” 的说明

这些修复程序可用于支持最低的浏览器,在全球范围内使用率超过 1%(IE6),这意味着使用:after 不会削减它。

隐藏的溢出确实会显示内容,但不会阻止元素崩溃,因此无法回答问题。使用内联块可能会产生错误的结果,孩子的页边距奇怪,等等,桌子要好得多。

设置高度可以 “防止” 塌陷,但这不是适当的解决方法。

无效的 CSS

无效的 CSS 永远不会伤害任何人,事实上,现在这已成为常态。使用浏览器前缀与使用特定于浏览器的黑客一样无效,并且不会对最终用户造成任何影响。

结论

我使用上述两种解决方案来使元素正确反应并彼此很好地玩耍,恳请您做同样的事情。

我在适用的地方使用 2 和 4(例如,当我知道内容的高度或溢出不会造成危害时)。在其他任何地方,我都使用解决方案 3。顺便说一句,您的第一个解决方案没有优于 3(我可以发现)的优势,因为它不再使用任何语义,因为它使用了相同的伪元素。

顺便说一句,我不会担心第四个解决方案是 hack。 CSS 中的 hack 仅在其基本行为受到重新解释或其他更改时才是有害的。这样,您的骇客就无法保证正常工作。但是,在这种情况下,您的 hack 依赖于overflow: auto的确切行为overflow: auto应该具有。搭便车没有害处。

我最喜欢的方法是使用 clearfix 类作为父元素

.clearfix:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}

.clearfix {
    display: inline-block;
}

* html .clearfix {
    height: 1%;
}

.clearfix {
    display: block;
}