块格式化上下文,折叠边距和浮动容器

时间:2016-10-07 15:03:45

标签: html css css-float css-position haslayout

为了理解块格式化上下文的作用,我试图找出当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>

请告诉我发生了什么。

1 个答案:

答案 0 :(得分:1)

好问题,让我思考了很多!

这里有很多概念,所以我将逐一介绍它们:

Buggy IE

如果您不必为IE7或IE8兼容模式设计,那么this中提到的关于IE的旧文章可以很容易地被忽略。此行为是由IE7内部使用的 hasLayout 属性引起的。

请参阅this MSDN doc了解IE7:

  

什么是“HasLayout”,为什么重要?

     

有几个错误   可以通过强制“布局”来解决的Internet Explorer(   元素上的IE内部数据结构。

显然,这是一种非标准的解决方法,同时也会带来很多不一致之处。请阅读此here


块格式上下文(BFC)

摘自this MDN doc

  

块格式化上下文是a的可视CSS呈现的一部分   网页。它是块框布局的区域   并且漂浮物彼此相互作用。

BFC对于浮动元素的定位和清除非常重要 - 浮动元素仅在相同的BFC内影响。当你float一个元素时,它会从流中取出并通过“浮动”重新插入。

请参阅以下示例:

  1. wrapper的内部是一个BFC,你将一个div向左浮动,另一个向右浮动。

  2. 浮动元素重新插入到BFC中,同时渲染未浮动的元素。

  3. 由于您没有clear在BFC中浮动,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>

  4. 看看当你{B}浮动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>


  5. 折叠边距

      

    块的顶部和底部边距有时会合并(折叠)   单个保证金,其大小是合并的最大边际   进入它,一种称为边缘崩溃的行为。

    相邻块父级和第一个/最后一个子空块的边距会崩溃。请参阅this MDN doc中有关边距折叠的详细信息。

    另请注意:

      

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



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

    1. 现在您将了解BFC以及浮动容器在第一种情况下的工作原理(当您没有指定边框时) - 这就是为什么floatMe不在其直接mainContent包装器中的原因以及为什么wrappermainContent的高度与它看起来一致。

    2. 布局 IE 仅在IE7中出现并且是非标准的。

    3. 其他所有事情都是因为保证金崩溃:

      一个。 h2pre页边距崩溃(相邻的兄弟姐妹

      mainContent稍微向上移动以使body父级和第一个/最后一个孩子)上的边距崩溃

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

      d。应用边框时会发生的情况是上面(b)中的边距折叠无效! (请参阅上面的MDN doc,了解原因)



    4. 希望现在看起来好多了。干杯!