【问题标题】:How do you keep parents of floated elements from collapsing? [duplicate]你如何防止浮动元素的父母崩溃? [复制]
【发布时间】:2010-09-18 03:21:24
【问题描述】:

虽然像<div>s 这样的元素通常会增长以适应其内容,但使用float 属性可能会给CSS 新手带来一个令人吃惊的问题:如果浮动元素有非浮动的父元素,则父元素会折叠。

例如:

<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>

优点:代码简单。
缺点:没有语义;间隔 div 仅作为布局技巧存在。

解决方案 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 属性的既定用途。

评论?其他建议?

【问题讨论】:

标签: html css layout css-float clearfix


【解决方案1】:

解决方案 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 中进行了测试。

【讨论】:

  • -1 100% 的内联块在您对该元素进行填充时会产生不良影响。 -1 : 在 ie6 中不起作用后
  • @lededje:IE6(见鬼,甚至 IE7)有一个损坏的浮动模型,任何类型的 clearfix 都无法完全修复。
  • @BoltClock 非常正确,我也从未在实际版本的浏览器中实际测试过这些,我使用(d)Adobe BrowserLab。
  • 像认真关心 IE6 的人一样:D IE8,我会理解,但即使 2012 年,IE6 也太多了:P
  • @davidtaubmann W3Schools不是官方标准或标准的一部分,它们由不隶属于 W3C 的第三方公司运营。尽管它们在过去几年中得到了很大的改进,但许多开发人员仍然认为它们是一个糟糕的信息来源。我建议您总体上查看 MDN 或 Web Platform Docs(远没有那么全面,但官方)。我省略了overflow: auto 技巧,因为在要求其他建议的问题中提到了它。
【解决方案2】:

我通常使用overflow: auto 技巧;虽然严格来说这不是溢出的预期用途,但它有点相关 - 足以让它容易记住,当然。 float: left 本身的含义已经扩展到各种用途,比在这个例子中的溢出更重要,IMO。

【讨论】:

  • 恭喜,这正是官方 w3 解决方案:w3schools.com/css/tryit.asp?filename=trycss_layout_clearfix
  • W3 != W3Schools,实际上 W3Schools 在标准 HTML 方面托管了非常“可疑”的内容。
  • 关于 W3Schools,我认为这些年来他们至少变得更好了,但重要的是要意识到这一点,就像 @D.R.说,他们不是万维网联盟(W3C)
【解决方案3】:

不要将overflow:auto放在父级上,而是放在overflow:hidden

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

div {
  overflow:hidden;
}

那我就不用担心了。

【讨论】:

  • 这是个坏主意。你不想随意剪裁任何东西,特别是如果你在这些 div 上设置了固定尺寸。此外,在某些情况下,overflow: autooverflow: hidden 更受欢迎(例如,您希望内容在溢出时可滚动)。
  • 自从我发布了这个,我已经停止使用它作为全局默认值。我确实认为overflow:hidden 通常是最好的解决方案。每个案例都是不同的。感谢您指出这一点;)
  • 没问题 - 我想我还是会为后代添加评论,以防它再次出现。
【解决方案4】:

当浮动元素位于容器框内时会出现问题,该元素不会自动强制容器的高度调整为浮动元素。当一个元素浮动时,其父元素不再包含它,因为浮动已从流中移除。您可以使用 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%;
}

Demonstration :)

【讨论】:

  • 我在 ie6 上遇到了浮动折叠我的 div 边框的问题。我添加了height: 0,它修复了 ie6 但破坏了 ie7 及更高版本。 :( 原来height: 1% 修复了 ie6 而不会破坏 ie7up!:D
【解决方案5】:

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;
}

【讨论】:

    【解决方案6】:

    虽然代码不是完全语义化的,但我认为在每个带有浮动的容器底部放置一个我称之为“清除 div”的东西会更直接。事实上,我在每个项目的重置块中都包含了以下样式规则:

    .clear 
    {
       clear: both;
    }
    

    如果您正在为 IE6 设计样式(上帝保佑您),您可能还想给这条规则设置一个 0px 的行高和高度。

    【讨论】:

    • 如果您的元素中有类似 Facebook 的“赞”框,则需要使用此方法,否则当您点击“赞”时,Facebook 评论框将被裁剪。跨度>
    【解决方案7】:

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

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

    【讨论】:

      【解决方案8】:

      奇怪,还没有人给出完整的答案,嗯,就是这样。

      解决方案一:明确:两者都

      添加样式为 clear:both 的块元素;到它上面将清除经过该点的浮动并阻止该元素的父元素折叠。 http://jsfiddle.net/TVD2X/1/

      优点:允许你清除一个元素,你在下面添加的元素不会受到上面的浮动元素和有效的 css 的影响。

      缺点:需要另一个标签来清除浮动,膨胀标记。

      注意:要回退到 IE6 并让它在禁欲的父母(即输入元素)上工作,你不能使用 :after。

      方案二:显示:表格

      添加显示:表格;给父母以使其摆脱浮动并以正确的高度显示。 http://jsfiddle.net/h9GAZ/1/

      优点:没有额外的标记,而且更整洁。适用于 IE6+

      缺点:需要无效的 css 以确保在 IE6 和 7 中一切正常。

      注意:IE6 和 7 的宽度自动用于防止宽度为 100%+padding,这在较新的浏览器中并非如此。

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

      这些修复可以回溯到支持最低的浏览器,全球使用率超过 1% (IE6),这意味着使用 :after 不会减少它。

      Overflow hidden 会显示内容,但不会阻止元素折叠,因此不会回答问题。使用内联块可能会产生错误的结果,孩子的边距奇怪等等,表格要好得多。

      设置高度确实“防止”塌陷,但这不是一个适当的修复方法。

      无效的 CSS

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

      总结

      我使用上述两种解决方案来使元素正确反应并相互配合,我恳请您也这样做。

      【讨论】:

      • IE6什么时候支持display: table
      • [rant] 请参阅caniuse.com/#feat=css-table,获取完整的兼容性列表。 IE 6 和 7 对 display: table;no 支持。至于您的其他解决方案,在要求“Other 建议”的问题中已经提到过。在提供您自己的答案和否决其他人之前,请阅读问题和所有答案。还有一点,无效的 CSS 可能不会“伤害”任何人,但无论如何它都是无效的 CSS,而且供应商前缀不仅仅是公认的规范,查看 Chrome 检查器,您会发现它不仅仅认为它们无效,它们根本不被处理。 [/咆哮]
      • [回应咆哮]首先,上述方法在IE6上进行了测试,它们所有都可以正常工作。提供一个无效的示例并回复我。供应商特定规则并不意味着在它们不适用的浏览器中处理(这就是供应商特定的意思......)所以是的,当然它们不会被处理......这就是重点,但它仍然允许您使用最前沿的 css 规则。[/response to rant]
      • 您的display: table 方法在IE6/IE7 中有效与display: table 无关,与zoom: 1 无关。请参阅jsfiddle.net/BoltClock/h9GAZ/2(已删除zoom: 1)和jsfiddle.net/BoltClock/h9GAZ/3(已删除display: table)。再加上“需要无效的 css [for] IE6 和 7”这句话,这类似于说该方法在这些版本中根本不起作用。
      • zoom 从未出现在任何 CSS 规范中……它是由 Microsoft 单独创建和使用的。
      【解决方案9】:

      我在适用的情况下使用 2 和 4(即,当我知道内容的高度或溢出不会造成伤害时)。在其他任何地方,我都会使用解决方案 3。顺便说一下,您的第一个解决方案与 3(我可以发现)相比没有优势,因为它不再是语义,因为它使用相同的虚拟元素。

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

      【讨论】:

      • 糟糕 - 我在第一个解决方案中删除了虚拟元素。那是个错误。感谢您指出。
      【解决方案10】:

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

      .clearfix:after {
          content: ".";
          display: block;
          height: 0;
          clear: both;
          visibility: hidden;
      }
      
      .clearfix {
          display: inline-block;
      }
      
      * html .clearfix {
          height: 1%;
      }
      
      .clearfix {
          display: block;
      }
      

      【讨论】:

        【解决方案11】:

        最著名的解决方案之一是解决方案 3 的变体,它使用伪元素而不是非语义 html 元素。

        事情是这样的......

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

        你把它放在你的样式表中,你所需要的只是将类'cf'添加到包含浮动的元素中。

        我使用的是来自 Nicolas Gallagher 的另一个变体。

        它做同样的事情,但它更短,看起来更整洁,并且可能用于完成另一件非常有用的事情 - 防止子元素的边距与其父元素折叠(但为此你确实需要其他东西 - 阅读更多信息在这里http://nicolasgallagher.com/micro-clearfix-hack/)。

        .cf:after {
            content: " ";
            display: table;
            clear: float;
        }
        

        【讨论】:

          【解决方案12】:

          将其添加到底部的父 div 中

           <div style="clear:both"></div>
          

          【讨论】:

            【解决方案13】:

            将溢出更改为autohidden 可能会发现的主要问题是,所有内容都可以通过鼠标中键滚动,并且用户可能会弄​​乱整个网站布局。

            【讨论】:

              【解决方案14】:

              我认为在语义上更正确的另一种可能的解决方案是将浮动内部元素更改为“显示:内联”。这个例子和当我遇到这个页面时我正在做的事情都使用浮动 div 的方式与使用 span 的方式几乎完全相同。不要使用 div,而是切换到 span,或者如果您使用的是默认情况下为 'display: block' 而不是 'display: inline' 的另一个元素,则将其更改为 'display: inline'。我相信这是 100% 语义正确的解决方案。

              方案一,浮动父级,本质上是将整个文档改为浮动。

              解决方案2,设置一个明确的高度,就像画一个盒子说我想在这里放一张图片,即如果你正在做一个img标签就使用这个。

              解决方案 3,添加一个间隔来清除浮动,就像在您的内容下方添加一个额外的行,并且也会与周围的元素混淆。如果您使用这种方法,您可能希望将 div 设置为 height: 0px。

              解决方案 4,溢出:自动,是承认您不知道如何布置文档并且您承认您不知道该做什么。

              【讨论】:

              • 你的意思是同时删除浮动声明吗?因为浮动元素不能是任何东西但是 display: block.
              【解决方案15】:

              我认为最好的方法是将clear:both 设置为即将到来的元素。

              原因如下:

              1) :after 选择器在 IE6/7 中不受支持,在 FF3 中不支持,但是,
                   如果您只关心 IE8+ 和 FF3.5+ 清除,使用 :after 可能最适合您...

              2) overflow 应该做其他事情,所以这个 hack 不够可靠。

              作者注意:清除没有什么hacky...清除意味着跳过浮动字段。 CLEAR 从 HTML3 开始就与我们同在(谁知道,可能更长)http://www.w3.org/MarkUp/html3/deflists.html,也许他们应该选择一个有点不同的名称,例如 page: new,但这只是一个细节......

              【讨论】:

                猜你喜欢
                • 2011-12-01
                • 2016-04-16
                • 1970-01-01
                • 2013-05-17
                • 1970-01-01
                • 2021-04-19
                • 2011-11-25
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多