1

为了了解块格式化上下文的作用,我试图找出创建 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 不同,正是该边距(不是黑框上的边距)在包装器上方创建了间隙。

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

我试图通过添加* {border: 1px solid blue;}到 CSS 来确定确切的布局,但在此更改之后整体布局发生了很大变化:现在它的行为就像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>

请告诉我发生了什么事。

4

1 回答 1

1

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

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

越野车 IE

如果您不必为 IE7 或 IE8 兼容模式进行设计,则很容易忽略这篇旧文章中提到的任何有关 IE 的内容。此行为是由于IE7 内部使用的hasLayout属性造成的。

有关IE7,请参阅此 MSDN 文档:

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

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

显然,这是一种非标准的解决方法,并且会带来很多不一致的地方。也可以在这里阅读。


块格式化上下文(BFC)

此 MDN 文档的摘录:

块格式化上下文是网页的可视 CSS 呈现的一部分。它是块框布局发生的区域以及浮动相互交互的区域。

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

请参阅以下示例:

  1. 内部wrapper是一个 BFC,您可以在其中将一个 div 浮动到左侧,将另一个 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. 看看当你在 BFC 中漂浮时会发生什么——现在高度将在BFCclear中正常运行。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;
        }
        .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>


折叠边距

块的顶部和底部边距有时会组合(折叠)成单个边距,其大小是组合到其中的边距中最大的,这种行为称为边距折叠。

相邻块父块和第一个/最后一个子块以及空块的边距折叠。在这个 MDN 文档中查看更多关于边距折叠的信息。

另请注意:

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



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

  1. 因此,现在您将了解 BFC 以及浮动容器在第一种情况下的工作原理(当您没有指定边界时)——这就是为什么要远离floatMe其直接mainContent包装器以及为什么它的高度wrappermainContent看起来在那里一样。

  2. 所指的布局IE仅在IE7中,是非标准的。

  3. 发生的所有其他事情都是因为边距崩溃:

    一个。h2pre边距折叠(相邻的兄弟姐妹

    湾。mainContent稍微移动到顶部以折叠body父母和第一个/最后一个孩子)上的边距

    C。随着wrapper的高度mainContentwrapper高度也向上移动。

    d。当您应用边框时会发生什么情况是上面(b)中折叠的边距无效!(有关原因,请参阅上面的 MDN 文档)



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

于 2016-10-07T18:04:47.023 回答