提问



我有一个div包装两列布局的古老问题。我的侧边栏是浮动的,所以我的容器div无法包装内容和侧边栏。


<div id="container">
  <div id="content"></div>
  <div id="sidebar"></div>
</div>


似乎有很多方法可以修复Firefox中的明确错误:



  • <br clear="all"/>

  • overflow:auto

  • overflow:hidden



在我的情况下,唯一似乎正常工作的是<br clear="all"/>解决方案,这有点邋.. overflow:auto给了我讨厌的滚动条,overflow:hidden肯定有副作用。
此外,IE7显然不应该因为其不正确的行为而遭受这个问题,但在我的情况下,它与Firefox的痛苦相同。


目前我们可以采用哪种方法最强大?

最佳参考


根据所生产的设计,以下每个clearfix CSS解决方案都有其自身的优点。


clearfix确实有用,但它也被用作黑客。在使用clearfix之前,这些现代css解决方案可能很有用:



  • css flexbox

  • css grid






Modern Clearfix Solutions






overflow: auto;

的容器

清除浮动元素的最简单方法是使用包含元素上的样式overflow: auto。此解决方案适用于所有现代浏览器。[107] [108]


<div style="overflow: auto;">
  <img
    style="float: right;"
    src="path/to/floated-element.png"
    width="500"
    height="500"
  > 
  <p>Your content here…</p>
</div>


一个缺点是,在外部元素上使用边距和填充的某些组合可能会导致滚动条出现,但这可以通过将边距和填充放在另一个包含父元素的元素上来解决。


使用'overflow:hidden'也是一个clearfix解决方案,但不会有滚动条,但是使用hidden将裁剪位于包含元素之外的任何内容。


注意:在此示例中,浮动元素是img标记,但可以是任何html元素。





Clearfix Reloaded



CSSMojo上的Thierry Koblentz写道:重新加载了最新的clearfix。他指出,通过放弃对oldIE的支持,可以将解决方案简化为一个css语句。此外,使用display: block(而不是display: table)允许边缘在具有clearfix的元素是兄弟节点时正确折叠。[109]


.container::after {
  content: "";
  display: block;
  clear: both;
}


这是clearfix的最现代版本。









较早的Clearfix解决方案



以下解决方案对于现代浏览器不是必需的,但对于定位旧浏览器可能是有用的。


请注意,这些解决方案依赖于浏览器错误,因此只有在上述解决方案都不适合您的情况下才能使用。


它们大致按时间顺序列出。





击败ClearFix,现代浏览器的clearfix



CSS Mojo的Thierry Koblentz指出,在针对现代浏览器时,我们现在可以删除zoom::before属性/值并简单地使用:[110]


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


此解决方案故意不支持IE 6/7!


Thierry还提供:请注意:如果你从头开始一个新项目,那就去做吧,但不要把这个技术换成你现在的那个,因为即使你不支持oldIE,你的现有规则也会阻止利润率下降。[111]





Micro Clearfix



最新和全球采用的clearfix解决方案,Nicolas Gallagher的Micro Clearfix。[112]


已知支持:Firefox 3.5 +,Safari 4 +,Chrome,Opera 9 +,IE 6 +


.container::before, .container::after {
  content: "";
  display: table;
}
.container::after {
  clear: both;
}
.container {
  zoom: 1;
}





溢出属性



当定位的内容不会显示在容器的边界之外时,这种基本方法对于通常的情况是优选的。


http://www.quirksmode.org/css/clearing.html
- 解释了如何解决与此技术相关的常见问题,即在容器上设置width: 100%[113]


.container {
  overflow: hidden;
  display: inline-block;
  display: block;
}


不是使用display属性为IE设置hasLayout,而是可以使用其他属性来触发元素的hasLayout。[114]


.container {
  overflow: hidden;
  zoom: 1;
  display: block;
}


使用overflow属性清除浮动的另一种方法是使用下划线黑客。 IE将应用前缀为下划线的值,其他浏览器则不会。 zoom属性在IE中触发hasLayout:[115] [116]


.container {
  overflow: hidden;
  _overflow: visible; /* for IE */
  _zoom: 1; /* for IE */
}


虽然这有效......但使用黑客并不理想。





PIE:简易清算方法



这种较旧的Easy Clearing方法的优点是允许定位元素悬挂在容器的边界之外,但代价是更棘手的CSS。


这个解决方案很老了,但你可以学到所有关于位置就是一切的简单清理:http://www.positioniseverything.net/easyclearing.html [117]





元素使用clear属性



快速和肮脏的解决方案(有一些缺点),当你快速拍打一起时:


<br style="clear: both" /> <!-- So dirty! -->


缺点




  • 如果布局样式根据媒体查询而改变,它没有响应,因此可能无法提供所需的效果。纯CSS中的解决方案更理想。

  • 它添加了html标记,但不必添加任何语义值。

  • 它需要每个实例的内联定义和解决方案,而不是对hss中css和类引用中的clearfix的单个解决方案的类引用。

  • 它使代码难以与其他人合作,因为他们可能不得不写更多的黑客来解决它。

  • 将来,当您需要/想要使用其他clearfix解决方案时,您不必返回并删除标记周围散布的每个<br style="clear: both" />标记。


其它参考1


我们试图解决哪些问题?



浮动时有两个重要的考虑因素:



  1. 包含后代浮动。这意味着所讨论的元素使其自身足够高以包裹所有浮动后代。 (他们不要挂在外面。)




  2. 从外部浮动绝缘后代。这意味着元素内部的后代应该能够使用clear: both并且不与元素外部的浮点交互。






阻止格式化上下文



只有一种方法可以做到这两点。那就是建立一个新的块格式化上下文。建立块格式化上下文的元素是一个绝缘矩形,其中浮点数互相交互。块格式化上下文总是很高足以在视觉上包裹它的浮动后代,并且块格式化上下文之外的任何浮点都不能与内部元素交互。这种双向绝缘正是你想要的。在IE中,这个相同的概念叫做hasLayout,可以通过[[zoom: 1[118] [119]


有几种方法可以建立块格式化上下文,但我推荐的解决方案是display: inline-blockwidth: 100%。 (当然,使用width: 100%时会有一些注意事项,所以使用box-sizing: border-box或将paddingmarginborder放在不同的元素上。)


最强大的解决方案



可能浮动的最常见应用是双列布局。 (可以扩展到三列。)


首先是标记结构。


<div class="container">
  <div class="sidebar">
    sidebar<br/>sidebar<br/>sidebar
  </div>
  <div class="main">
    <div class="main-content">
      main content
      <span style="clear: both">
        main content that uses <code>clear: both</code>
      </span>
    </div>
  </div>
</div>


而现在的CSS。


/* Should contain all floated and non-floated content, so it needs to
 * establish a new block formatting context without using overflow: hidden.
 */
.container {
  display: inline-block;
  width: 100%;
  zoom: 1; /* new block formatting context via hasLayout for IE 6/7 */
}

/* Fixed-width floated sidebar. */
.sidebar {
  float: left;
  width: 160px;
}

/* Needs to make space for the sidebar. */
.main {
  margin-left: 160px;
}

/* Establishes a new block formatting context to insulate descendants from
 * the floating sidebar. */
.main-content {
  display: inline-block;
  width: 100%;
  zoom: 1; /* new block formatting context via hasLayout for IE 6/7 */
}


亲自尝试



转到JS Bin来使用代码,看看这个解决方案是如何从头开始构建的。[121]


传统的clearfix方法被认为是有害的



传统的clearfix解决方案的问题在于它们使用两种不同的渲染概念来实现IE和其他所有人的相同目标。在IE中,他们使用hasLayout来建立一个新的块格式化上下文,但是对于其他人来说,他们使用生成的框[[:after)和clear: both,它们不会建立新的块格式化上下文。这意味着事情在所有情况下都不会表现得相同。为了解释为什么这很糟糕,请参阅关于Clearfix的所有内容都是错误的。[122] [123] [124]

其它参考2


新标准,由Inuit.css和Bourbon使用 - 两个使用非常广泛且维护良好的CSS/Sass框架:[125] [126]


.btcf:after {
    content:"";
    display:block;
    clear:both;
}





注释



请记住,clearfixes本质上是一个很好的方式,现在可以以更智能的方式提供flexbox布局。 CSS浮动最初设计用于内联流内容 - 如长文本文章中的图像 - 而不是网格布局等。如果您的目标浏览器支持flexbox,则值得研究。[127] [128]


这并不支持IE7。你不应该支持IE7。这样做会继续使用户暴露于不固定的安全漏洞,并使所有其他Web开发人员的生活更加艰难,因为它减少了用户和组织切换到现代浏览器的压力。


这个clearfix是由Thierry Koblentz在2012年7月宣布和解释的。它从Nicolas Gallagher的2011微型clearfix中减轻了不必要的重量。在这个过程中,它释放了一个伪元素供你自己使用。这已被更新为使用display: block而不是display: table(再次归功于Thierry Koblentz)。[129] [130]

其它参考3


我推荐使用以下内容,摘自http://html5boilerplate.com/[131]


/* >> The Magnificent CLEARFIX << */


.clearfix:after { 
  content: "."; 
  display: block; 
  height: 0; 
  clear: both; 
  visibility: hidden; 
}
.clearfix { 
  display: inline-block;  
}
* html .clearfix {  
  height: 1%;  
} /* Hides from IE-mac \*/
.clearfix {  
  display: block;  
}

其它参考4


overflow属性可用于清除浮动而无需额外标记:


.container { overflow: hidden; }


这适用于除IE6之外的所有浏览器,您需要做的就是启用hasLayout(缩放是我首选的方法):


.container { zoom: 1; }


http://www.quirksmode.org/css/clearing.html[132]

其它参考5


我在CLEARFIX官方方法中发现了一个错误:
DOT没有字体大小。
如果你设置height = 0并且DOM-Tree中的第一个元素具有clearfix类,那么你总是在12px的页面底部有一个边距:)


你必须像这样解决它:


/* float clearing for everyone else */
.clearfix:after{
  clear: both;
  content: ".";
  display: block;
  height: 0;
  visibility: hidden;
  font-size: 0;
}


它现在是YAML-Layout的一部分......只需看看它 - 它非常有趣!
http://www.yaml.de/en/home.html[133]

其它参考6


这是一个非常整洁的解决方案:


/* For modern browsers */
.cf:before,
.cf:after {
    content:"";
    display:table;
}

.cf:after {
    clear:both;
}

/* For IE 6/7 (trigger hasLayout) */
.cf {
    zoom:1;
}



  众所周知,它适用于Firefox 3.5 +,Safari 4 +,Chrome,Opera 9 +,IE 6+

  
  包括:before选择器不需要清除浮动,
  但它可以防止顶级边距在现代浏览器中崩溃。这个
  确保在缩放时与IE 6/7具有视觉一致性:1
  应用。



来自http://nicolasgallagher.com/micro-clearfix-hack/[134]

其它参考7


来自bootstrap的Clearfix:


.clearfix {
  *zoom: 1;
}

.clearfix:before,
.clearfix:after {
  display: table;
  line-height: 0;
  content: "";
}

.clearfix:after {
  clear: both;
}

其它参考8


我只是用: -


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


效果最好,兼容IE8 + :)

其它参考9


鉴于我不会发布大量的回复。但是,这种方法可能对某些人有所帮助,因为它确实帮助了我。


尽可能远离花车



值得一提的是,我避免像埃博拉这样的漂浮物。有很多原因,我并不孤单;阅读Rikudo关于什么是clearfix的答案,你会看到我的意思。用他自己的话来说:...the use of floated elements for layout is getting more and more discouraged with the use of better alternatives...


除了花车之外,还有其他好的(有时更好的)选择。随着技术的进步和改进,flexbox(和其他方法)将被广泛采用,浮动将成为一个糟糕的记忆。也许是CSS4?[136]





浮动不当行为和失败清除



首先,有时候,你可能会认为你的浮子是安全的,直到你的救生员被刺破并且你的html流开始下沉:


在下面的codepen http://codepen.io/omarjuvera/pen/jEXBya中,用<div classs="clear"></div>(或其他元素)清除浮动的做法很常见,但是皱眉和反语义。[137]


<div class="floated">1st</div>
<div class="floated">2nd</div>
<div class="floated">3nd</div>
<div classs="clear"></div> <!-- Acts as a wall -->
<section>Below</section>


CSS


div {
    border: 1px solid #f00;
    width: 200px;
    height: 100px;
}

div.floated {
    float: left;
}

.clear {
    clear: both;
}
section {
    border: 1px solid #f0f;
}


然而,就在你认为你的浮标值得开航的时候......热潮!随着屏幕尺寸越来越小,您会看到如下图所示的奇怪行为(相同http://codepen.io/omarjuvera/pen/jEXBya):[138]





你为什么要关心?
我不确定具体数字,但大约80%(或更多)使用的设备是具有小屏幕的移动设备。台式电脑/笔记本电脑不再是王道。





它没有结束



这不是浮动的唯一问题。有很多,但在这个例子中,有些人可能会说all you have to do is to place your floats in a container。但正如您在codepen和图形中看到的那样,情况并非如此。这显然使事情变得更糟:[139]


HTML


<div id="container" class="">
  <div class="floated">1st</div>
  <div class="floated">2nd</div>
  <div class="floated">3nd</div>
</div> <!-- /#conteiner -->
<div classs="clear"></div> <!-- Acts as a wall -->
<section>Below</section>


CSS


#container {
  min-height: 100px; /* To prevent it from collapsing */
  border: 1px solid #0f0;
}
.floated {
    float: left;
    border: 1px solid #f00;
    width: 200px;
    height: 100px;
}

.clear {
    clear: both;
}
section {
    border: 1px solid #f0f;
}


至于结果呢?


一样的!



至少你知道,你将开始一个CSS派对,邀请各种选择器和属性参加派对;制作一个比你开始时更糟糕的CSS。只是为了修复你的浮动。





CSS Clearfix救援



这个简单且适应性强的CSS是一个美丽和救世主:


.clearfix:before, .clearfix:after { 
    content: "";
    display: table;
    clear: both;
    zoom: 1; /* ie 6/7 */
}


这就是它!它真的有效而不破坏语义,我提到它有效吗?:[140]


来自同一个示例... HTML


<div class="clearfix">
    <div class="floated">1st</div>
    <div class="floated">2nd</div>
    <div class="floated">3nd</div>
</div>
<section>Below</section>


CSS


div.floated {
    float: left;
    border: 1px solid #f00;
    width: 200px;
    height: 100px;
}
section {
        border: 4px solid #00f;
}


.clearfix:before, .clearfix:after { 
    content: "";
    display: table;
    clear: both;
    zoom: 1; /* ie 6/7 */
}





现在我们不再需要<div classs="clear"></div> <!-- Acts as a wall -->并保持语义警察的快乐。这不是唯一的好处。这个clearfix响应任何屏幕大小,而不使用@media最简单的形式。换句话说,它将保持您的浮动容器的检查和防止洪水。最后,它提供对所有旧浏览器的支持一小空手道斩=)


这里再次是clearfix



.clearfix:before, .clearfix:after { 
    content: "";
    display: table;
    clear: both;
    zoom: 1; /* ie 6/7 */
}

其它参考10


我总是浮动网格的主要部分并将clear: both;应用于页脚。这不需要额外的div或类。

其它参考11


说实话;所有解决方案似乎都是修复渲染错误的黑客...我错了吗?


我发现<br clear="all" />是最简单,最简单的。看到class="clearfix"到处都不能触及那些反对外来市场元素的人的感情,是吗?你只是在不同的画布上绘制问题。


我也使用display: hidden解决方案,这很好,不需要额外的类声明或html标记...但有时你需要元素溢出容器,例如。漂亮的丝带和腰带

其它参考12


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


关于clearfix还有其他不同的开发者概念
http://www.wpreads.com/2013/03/floating-elements-css-clearfix.html[141]

其它参考13


我已经尝试了所有这些解决方案,当我使用下面的代码时,会自动为<html>元素添加一个大的余量:


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


最后,我通过将font-size: 0;添加到上面的CSS来解决边缘问题。

其它参考14


使用SASS,clearfix是:


@mixin clearfix {
    &:before, &:after {
        content: '';
        display: table;
    }
    &:after {
        clear: both;
    }
    *zoom: 1;
}


它的使用方式如下:


.container {
    @include clearfix;
}


如果你想要新的clearfix:


@mixin newclearfix {
    &:after {
        content:"";
        display:table;
        clear:both;
    }
}

其它参考15


使用LESS(http://lesscss.org/),可以创建一个方便的clearfix助手:[142]


.clearfix() {
  zoom: 1;
  &:before { 
    content: ''; 
    display: block; 
  }
  &:after { 
    content: ''; 
    display: table; 
    clear: both; 
  }
}


然后将其与有问题的容器一起使用,例如:


<!-- HTML -->
<div id="container">
  <div id="content"></div>
  <div id="sidebar"></div>
</div>


/* LESS */
div#container {
  .clearfix();
}

其它参考16


如果浮动容器具有父元素,则使用overflow:hidden/auto和ie6的高度就足够了。


其中一个#test可以工作,对于下面说明的HTML来清除浮动。


#test {
  overflow:hidden; // or auto;
  _height:1%; forces hasLayout in IE6
}

<div id="test">
  <div style="floatLeft"></div>
  <div style="random"></div>
</div>


如果拒绝使用ie6,只需浮动父项以清除浮动。


#test {
  float: left; // using float to clear float
  width: 99%;
}


从来没有真正需要任何其他类型的清算。也许这就是我写HTML的方式。

其它参考17


我也浮动#content,这样两列都包含浮点数。另外因为它可以让你清除#content内的元素而不清除侧栏。


与包装器相同的是,你需要使它成为一个块格式化上下文来包装两列。


本文提到了一些可以使用的触发器:
阻止格式化上下文。[143]

其它参考18


clearfix是元素自动清除后的一种方式,
这样你就不需要添加额外的标记了。


.clearfix:after {
   content: " "; /* Older browser do not support empty content */
   visibility: hidden;
   display: block;
   height: 0;
   clear: both;
}
.cleaner {
  clear: both;
}


通常你需要做如下的事情:


<div style="float: left;">Sidebar</div>
<div class="cleaner"></div> <!-- Clear the float -->


使用clearfix,您只需要


<div style="float: left;" class="clearfix">Sidebar</div>
<!-- No Clearing div! -->

其它参考19


为什么只是尝试使用css hack来完成1行HTML工作。为什么不使用语义html tu put break返回行?


我真的很好用:


<br style="clear:both" />


如果你不想在你的HTML中使用任何风格,你只需要使用课程来休息

并将.clear { clear:both; }放入CSS中。


优点:



  • html的语义用法返回行

  • 如果没有CSS加载,它将起作用

  • 无需额外的CSS代码和Hack

  • 无需使用CSS模拟br,它已经存在于HTML


其它参考20


假设您正在使用此HTML结构:


<div id="container">
  <div id="content">
  </div>
  <div id="sidebar">
  </div>
</div>


这是我要使用的CSS:


div#container {
    overflow: hidden;    /* makes element contain floated child elements */
}

div#content, div#sidebar {
    float: left;
    display: inline;    /* preemptively fixes IE6 dobule-margin bug */
}


我一直使用这个设置,它对我来说很好,即使在IE6中也是如此。

其它参考21


我总是使用 micro-clearfix :[144]


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

.cf:after {
    clear: both;
}

/**
 * For IE 6/7 only
 */
.cf {
    *zoom: 1;
}


Cascade Framework 中,我甚至默认在块级元素上应用它。 IMO,默认情况下在块级元素上应用它会使块级元素比其传统行为更直观。它还使我更容易将旧版浏览器的支持添加到Cascade Framework(它支持IE6-8以及现代浏览器)。[145]

其它参考22


与其他clearfixes不同,这里是一个没有容器的开放式



其他clearfixs要么浮动元素在一个标记良好的容器中,要么需要一个额外的,语义上空的<div>。相反,明确分离内容和标记需要一个严格的CSS解决方案来解决这个问题。


事实上,人们需要标记浮动的结尾,不允许无人看管的CSS排版[146]


如果后者是你的目标,浮动应该保持开放状态(段落,有序和无序列表等)以包裹它,直到遇到clearfix。例如,clearfix可能由新标题设置。


这就是我使用以下clearfix和新标题的原因:


h1 {
    clear: both;
    display: inline-block;
    width: 100%;
}


这个解决方案在我的网站上被广泛使用来解决问题:浮动缩小版旁边的文字很短,下一个清算对象的上边距不受尊重。[147]


当从站点自动生成PDF时,它还可以防止任何手动干预。
这是一个示例页面。[148] [149]

其它参考23


新的显示值似乎在一行中。


display: flow-root;


从w3规范:元素生成一个块容器框,并使用流布局布置其内容。它总是为其内容建立一个新的块格式化上下文。


信息:
https://www.w3.org/TR/css-display-3/#valdef-display-flow-root
https://www.chromestatus.com/feature/5769454877147136[150][151]


※如上面的链接所示,支持目前有限,因此可能会使用如下的后备支持:
https://github.com/fliptheweb/postcss-flow-root[152]

其它参考24


你也可以把它放在你的CSS中:


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

*:first-child+html .cb{zoom: 1} /* for IE7 */


并将类cb添加到您的父div:


<div id="container" class="cb">


您不需要在原始代码中添加任何其他内容......

其它参考25




#content{float:left;}
#sidebar{float:left;}
.clear{clear:both; display:block; height:0px; width:0px; overflow:hidden;}

<div id="container">
  <div id="content">text 1 </div>
  <div id="sidebar">text 2</div>
  <div class="clear"></div>
</div>



你试过这个:


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


我对这种方法没有任何问题。

其它参考26


我最喜欢的方法是在我的css/scss文档中创建一个clearfix类,如下所示


.clearfix{
    clear:both
}


然后在我的html文档中调用它,如下所示


<html>
  <div class="div-number-one">
    Some Content before the clearfix
  </div>

  <!-- Let's say we need to clearfix Here between these two divs --->
  <div class="clearfix"></div>

  <div class="div-number-two">
    Some more content after the clearfix
  </div>
</html>