CSS基础:margin重叠与负值 / 什么是BFC

413 阅读4分钟

margin 重叠与负值

一、margin 纵向重叠

与横向不同,margin 纵向重叠取重叠区最大值,不进行叠加。

如下:

<style>
      .container {
        width: 400px;
        height: 200px;
        background-color: blanchedalmond;
      }
      .container > div:first-child {
        background-color: blueviolet;
        width: 100%;
        height: 100px;
        margin-bottom: 100px;
      }
      .container > div:nth-child(2) {
        background-color: aquamarine;
        width: 100%;
        height: 50px;
        margin-top: 50px;
      }
</style>

<body>
    <div class="container">
      <div></div>
      <div></div>
    </div>
</body>

效果图如下:

当然父子元素直接也如此。

二、margin 负值问题

  • margin-top和margin-left 是负值,元素会向上或者向左移动
  • margin-right 负值,右侧元素左移,自身不受影响
  • margin-bottom负值,下侧元素上移,自身不受影响

BFC

BFC

一、是什么

BFC,即块格式化上下文(Block Formatting Context),是一块独立的渲染区域,决定了其子元素将如何定位,以及和其他元素的关系、相互作用。BFC内部元素的渲染不会影响边界以外的元素,并且有一套渲染规则:

  • 内部的盒子会在垂直方向上一个接一个的放置;
  • 对于同一个BFC的俩个相邻的盒子的margin会发生重叠,与方向无关;
  • 每个元素的左外边距与包含块的左边界相接触(从左向右),即使浮动元素也是如此。(这说明BFC中子元素不会超出他的包含块,但是注意position为absolute的元素是可以超出他的包含块边界);
  • BFC的区域不会与float的元素区域重叠;
  • 计算BFC的高度时,浮动子元素也参与计算;
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。

Block fomatting context = block-level box + Formatting Context

box即盒子模型,block-level box即块级元素。

Formatting context是W3C CSS2.1规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系、相互作用。最常见的 Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context(简称IFC)。

也就是说,BFC,只有 block-level box 参与,它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。

二、触发条件

触发 BFC 的条件有:

  • 根元素(<html>)
  • 浮动元素(元素的 float 不是 none
  • 绝对定位元素(元素的 positionabsolutefixed
  • 行内块元素(元素的 displayinline-block
  • 表格单元格(元素的 displaytable-cell,HTML表格单元格默认为该值)
  • 表格标题(元素的 displaytable-caption,HTML表格标题默认为该值)
  • 匿名表格单元格元素(元素的 displaytable、``table-rowtable-row-group、``table-header-group、``table-footer-group(分别是HTML table、row、tbody、thead、tfoot 的默认属性)或 inline-table
  • overflow 计算值(Computed)不为 visible 的块元素
  • display 值为 flow-root 的元素
  • contain 值为 layoutcontent 或 paint 的元素
  • 弹性元素(displayflexinline-flex 元素的直接子元素)
  • 网格元素(displaygridinline-grid 元素的直接子元素)
  • 多列容器(元素的 column-countcolumn-width (en-US) 不为 auto,包括 ``column-count1
  • column-spanall 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中。

备注:加粗为较常用的。

三、应用场景

1. 清除内部浮动

BFC在计算高度时,浮动元素也会参与。

清除浮动前:

清除浮动后:

<style>
      .container {
        width: 200px;
        border: 2px solid brown;
        /* display: flow-root; 清除内部浮动 */
      }
      .container > div {
        background-color: blueviolet;
        opacity: 0.3;
        float: left;
        width: 100px;
        height: 100px;
      }
</style>
<body>
    <div class="container">
      <div></div>
    </div>
</body>

2. 防止 margin 重叠(坍塌)

margin 坍塌:

使用 BFC 防止 margin 坍塌后:

father 父元素的设置了 margin-bottom: 50pxchild 子元素设置了 margin-bottom ,理想情况下下方的蓝色块应该距离 child 元素(绿块)100px,然而显然不是,因为发生了 margin 重叠/坍塌。 此时,通过给 father 设置一个 BFC 就可以解决这个问题了。

<style>
      body {
        background-color: blanchedalmond;
      }
      .father {
        margin-bottom: 50px;
        /* display: flow-root; 防止 margin 坍塌*/
      }
      .child {
        height: 100px;
        width: 200px;
        margin-bottom: 50px;
        background-color: lightgreen;
      }
      .blue {
        height: 100px;
        width: 200px;
        background-color: lightblue;
      }
</style>
<body>
    <div class="father">
      <div class="child">child</div>
    </div>
    <div class="blue"></div>
</body>

以上演示了 child 元素和 father 元素的 margin 塌陷问题,通过设置 display: flow-root 来解决。display: flow-root 是一个新的 display 属性的值,它可以创建无副作用的 BFC。

3. 自适应多栏布局

这里列举一个两栏布局,三栏布局待后面文章详细列举说明。

<style>
      .aside {
        width: 100px;
        height: 200px;
        float: left;
        background-color: black;
        opacity: 0.2; /* 为了方便演示效果 */
      }

      .main {
        height: 200px;
        background-color: plum;
        display: flow-root; /* 设置BFC,使main可以自适应 */
      }
</style>
<body>
    <div class="aside"></div>
    <div class="main"></div>
</body>

因为为 aside 元素设置了浮动,所以 main 的左边会与包含块的左边相接触,如下图:

为了达到两栏布局 asidemain 互不影响的效果,为 main 设置 BFC ,实现自适应布局效果,如下图:

参考文献