为了了解块格式化上下文的作用,我试图找出未创建BFC时发生的情况。

我从Everything you Know about Clearfix is Wrong进行了以下演示:



.wrapper {
  width: 740px;
  background: #cccccc;
}
.leftSidebar {
  float: left;
  width: 200px;
}
.rightSidebar {
  float: right;
  width: 200px;
}
.mainContent {
  padding-right: 200px;
  padding-left: 200px;
}
.floatMe {
  float: left;
  background: teal;
  color: #fff;
}

<div class="wrapper">
  <div class="leftSidebar">
    <h2>Heading</h2>
    <pre>.leftSidebar {
  float:left;
  width:200px;
}</pre>
  </div>
  <div class="rightSidebar">
    <h2>Heading</h2>
    <pre>.rightSidebar {
  float:right;
  width:200px;
}</pre>
  </div>
  <div class="mainContent">
    <h2>Heading</h2>
    <pre>.mainContent {
  padding-right:200px;
  padding-left:200px;
}</pre>
    <div class="floatMe">
      <pre>.floatMe {
  float:left;
  background:teal;
  color:#fff;
}</pre>
    </div>
  </div>
</div>





根据该文章(重点是我的):


  在现代浏览器中:
  
  所有元素都属于同一块格式上下文,因此相邻
  利润率下降。标题的边距从包装纸“伸出”到
  与p对接。与IE中不同,它是保证金(不是
  黑盒),从而在包装纸上方形成间隙。


我无法理解“相同的块格式设置上下文”指的是什么。我想知道为什么在没有块格式设置上下文的情况下产生这种奇怪的布局。

我试图通过在CSS中添加* {border: 1px solid blue;}来找出确切的布局,但是总体布局在此更改后发生了很大变化:现在,它的行为就好像wrapper是块格式化上下文一样!



.wrapper {
  width: 740px;
  background: #cccccc;
}
.leftSidebar {
  float: left;
  width: 200px;
}
.rightSidebar {
  float: right;
  width: 200px;
}
.mainContent {
  padding-right: 200px;
  padding-left: 200px;
}
.floatMe {
  float: left;
  background: teal;
  color: #fff;
}
* {
  border: 1px solid blue;
}

<div class="wrapper">
  <div class="leftSidebar">
    <h2>Heading</h2>
    <pre>.leftSidebar {
  float:left;
  width:200px;
}</pre>
  </div>
  <div class="rightSidebar">
    <h2>Heading</h2>
    <pre>.rightSidebar {
  float:right;
  width:200px;
}</pre>
  </div>
  <div class="mainContent">
    <h2>Heading</h2>
    <pre>.mainContent {
  padding-right:200px;
  padding-left:200px;
}</pre>
    <div class="floatMe">
      <pre>.floatMe {
  float:left;
  background:teal;
  color:#fff;
}</pre>
    </div>
  </div>
</div>





请告诉我发生了什么事。

最佳答案

好问题,让我想了很多!

这里有很多概念在起作用,所以我将一一介绍它们:

越野车IE:

如果不必为IE7或IE8兼容模式进行设计,则this旧文章中有关IE的任何内容都可以轻松忽略。此行为是由于IE7内部使用了hasLayout属性。

有关IE7,请参见this MSDN doc


  什么是“ HasLayout”,为什么它很重要?
  
  有几个错误
  可以通过强制使用“布局”(
  IE内部数据结构)上的元素。


显然,这是一种非标准的解决方法,并且会带来很多不一致之处。也了解此here


块格式化上下文(BFC):

this MDN doc的节选:


  块格式设置上下文是可视化CSS渲染的一部分
  网页。该区域是积木框布局的区域
  并且其中的花车彼此互动。


BFC对于浮动元素的定位和清除非常重要-浮动元素仅在相同的BFC中影响。当您float元素时,该元素将从流程中移出并通过“浮动”重新插入。

请参阅以下示例:


wrapper的内部是一个BFC,您在其中向左浮动一个div,向右浮动另一个div。
在围绕未浮动的元素进行渲染时,将浮动的元素重新插入到BFC中。
由于尚未在BFC中clear浮动,因此wrapper高度将扩展到未浮动元素的大小。



    body{
      margin: 0;
    }
    *{
      box-sizing: border-box;
    }
    .wrapper{
      border: 1px solid;
    }
    .wrapper > * {
      display: inline-block;
      border: 1px solid red;
      width: 33.33%;
      height: 100px;
    }
    .left{
      float: left;
    }
    .right{
      float: right;
    }
    .center{
      height: 50px;
    }

    <div class="wrapper">
      <div class="left">Left</div>
      <div class="center">Center</div>
      <div class="right">Right</div>
    </div>




看看当您在BFC中clear浮动时会发生什么,现在高度在wrapper BFC中将正常运行。



    body{
      margin: 0;
    }
    *{
      box-sizing: border-box;
    }
    .wrapper{
      border: 1px solid;
    }
    .wrapper > * {
      display: inline-block;
      border: 1px solid red;
      width: 33.33%;
      height: 100px;
    }
    .left{
      float: left;
    }
    .right{
      float: right;
    }
    .center{
      height: 50px;
    }
    .wrapper:after{
      content: '';
      display: block;
      clear: both;
    }

    <div class="wrapper">
      <div class="left">Left</div>
      <div class="center">Center</div>
      <div class="right">Right</div>
    </div>







崩溃的利润率:


  块的顶部和底部边距有时会合并(折叠)
  变成一个单一的边距,其大小是合并的最大边距
  它被称为边缘崩溃的行为。


相邻块,父块和第一个/最后一个子块以及空块的边距折叠。在this MDN doc中查看有关保证金崩溃的更多信息。

另请注意:


  浮动元素和绝对定位元素的边距永远不会崩溃。



那么这里到底发生了什么?


因此,现在您将了解BFC,以及第一种情况(当您未指定边框时)浮动容器的工作原理-这就是floatMe远离其直接mainContent包装器的原因,以及为什么wrappermainContent就像那里一样。
引用的Layout和IE仅在IE7中,并且是非标准的。
发生的其他所有情况都是由于保证金崩溃:

一种。 h2pre边距倒塌(相邻的兄弟姐妹)

b。 mainContent稍微移到顶部,以body上的空白折叠(父级和第一个/最后一个孩子)

C。当wrapper占据mainContent的高度时,wrapper的高度也会向上移动。

d。当您应用边框时,上面(b)中崩溃的边距将变为无效! (有关原因,请参见上面的MDN文档)




希望现在情况好转。干杯!

关于html - 块格式设置上下文,边距折叠和 float 容器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39920386/

10-11 07:56