让你彻底明白什么是BFC及作用?

1.什么是BFC?

BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域, 它规定了内部的Block Box如何布局,并且与这个区域外部毫不相干。个人理解,BFC也是属于普通流的一种,BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。

2.BFC的布局规则?
  1. 内部的Box会在垂直方向,一个接一个地放置。(感觉是废话!普通流也是这样)
  2. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
  3. 每个元素的左外边缘(margin-left), 与包含块的左边(contain box left)相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。除非这个元素自己形成了一个新的BFC。
  4. BFC的区域不会与float box重叠。
  5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  6. 计算BFC的高度时,浮动元素也参与计算
3.BFC的触发条件?
  1. 根元素(html)
  2. 浮动 (元素的 float 不是 none)
  3. 绝对定位的元素 (元素具有 position 为 absolute 或 fixed)
  4. 非块级元素具有 display: inline-block,table-cell, table-caption, flex, inline-flex
  5. 块级元素具有overflow ,且值不是 visible
4.根元素触发了BFC,到底是html,body哪个触发了BFC?

找了很多资料,也没有给出官方的回答,那么只能通过自己的验证来回答这个问题?

<style>
    * {
        margin: 0;
        padding: 0;
    }
    html {
        background-color: lightsalmon;
    }
    body {
        background-color: grey;
    }
    .one,
    .two {
        float: left;
        background-color: green;
        width: 200px;
        height: 200px;
    }
    .two {
        background-color: hotpink;
    }
</style>

<body>
    <div class="one"></div>
    <div class="two"></div>
</body>

在这里插入图片描述
由上图可以看出,body里面两个子元素浮动让body高度为0,说明body并没有创建BFC

<style>
    * {
        margin: 0;
        padding: 0;
    }
    html {
        background-color: lightsalmon;
    }
    body {
        float: left;
        height: 500px;
        background-color: grey;
    }  
</style>

在这里插入图片描述
从上图可以看到,body元素浮动了,html同样有高度,所以html创建了BFC

4.1 关于用overflow:hidden触发不了body元素BFC的疑问?

继续看上面验证body是否创建BFC的代码,下面我用 overflow: hidden触发body元素创建BFC

   body {
        background-color: grey;
        overflow: hidden;
    }

在这里插入图片描述
结果还是一样,body还是没有高度,难道创建BFC失效?先引用一段w3c对BFC定义的原文

Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with ‘overflow’ other than ‘visible’ (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.

上面英文描述如果overflow不是visible的块级元素将创建BFC。但是要注意里面有这么一句话** except when that value has been propagated to the viewport** 意思为除非该值已经扩散到了视口。

然后我们先看overflow的w3c定义的原文

UAs must apply the ‘overflow’ property set on the root element to the viewport. When the root element is an HTML “HTML” element or an XHTML “html” element, and that element has an HTML “BODY” element or an XHTML “body” element as a child, user agents must instead apply the ‘overflow’ property from the first such child element to the viewport, if the value on the root element is ‘visible’. The ‘visible’ value when used for the viewport must be interpreted as ‘auto’. The element from which the value is propagated must have a used value for ‘overflow’ of ‘visible’.

大概意思是:

  1. UAs需要将根元素上的overflow属性置于视口之上。
  2. overflow扩散行为:当根元素是html元素且overflow为visible,而且html元素有body作为其子元素,UAs则需要将第一个body之上的overflow属性应用于视口。
  3. 用于视口的overflow: visible将被解析为overflow: auto。
  4. overflow扩散行为将导致body的overflow属性为visible。

说的直白点的话就是html元素的overflow默认属性是visible,导致body元素的overflow:hidden被应用于视口,导致body元素的overflow属性最终为visible,因此body没有触发BFC。所以只能先将html元素的overflow属性设置为hidden,再把body元素的overflow属性设置为hidden,才能使body触发BFC 。下面我们再来测试一下!

    html {
        background-color: lightsalmon;
        overflow: hidden;
    }

    body {
        background-color: grey;
        overflow: hidden;
    }

在这里插入图片描述

测试结果是对的,基本上可以得出结论:

  1. 给body加上overflow:hidden,无法触发BFC创建。因为body {overflow:hidden} html {overflow: visible}(html为默认overflow: visible),body的overflow:hidden被应用于视口,body的最终使用值为overflow:visible,因此body没有创建BFC。

  2. 给body和html同时加上overflow:hidden,成功触发BFC创建。因为body, html{overflow:hidden},html的overflow:hidden被用于视口,body的overflow计算值是hidden,因此创建了BFC。

  3. 给body加上display:table、display:inline-block、position:absolute,成功触发BFC创建。

5.BFC的应用场景
5.1 清除浮动(高度坍塌)
<style>
    * {
        margin: 0;
        padding: 0;
    }

    .container{
        overflow: hidden;
    }

    .one,
    .two {
        float: left;
        background-color: green;
        width: 200px;
        height: 200px;
    }

    .two {
        background-color: hotpink;
    }
</style>

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

在这里插入图片描述
原理和上面的body一样,这里不多说了,这里补充一点,clear:both也可以清除浮动,但是它和创建BFC原理不一样, clear:both一般都是在浮动元素最后面的那个元素使用,他的原理使该元素的上外边框边界刚好在该边上浮动元素的下外边距边界之下,说白话就是让自己跑到原先在自己前面的浮动元素下面待着,于是父元素就会被撑开,没办法,谁让我有这么个儿子(儿子指代当前添加clear:both普通元素,因为还在标准文档流中,所以将父元素撑开)呢,至此我们就利用clear:both属性实现了清除浮动。

5.2 防止外边距折叠
<style>
    * {
        margin: 0;
        padding: 0;
    }
    .one,
    .two {
        background-color: green;
        width: 200px;
        height: 200px;
        margin: 100px;
    }

    .two {
        background-color: hotpink;
    }
</style>

<body>
    <div class="one"></div>
    <div class="two"></div>
</body>

在这里插入图片描述
上图两个div的距离是100px,因为两个相邻Box的margin会发生重叠,以最大的margin为准,这里都是100px,所以距离是100px

<style>
    * {
        margin: 0;
        padding: 0;
    }

    .container {
        overflow: hidden;
    }

    .one,
    .two {
        background-color: green;
        width: 200px;
        height: 200px;
        margin: 100px;
    }

    .two {
        background-color: hotpink;
    }
</style>

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

在这里插入图片描述
我们添加一个container元素并触BFC,两个div的外边距就变成两个外边距之和等于200px了

5.3 防止外边距溢出
<style>
    * {
        margin: 0;
        padding: 0;
    }
    .container{
        width: 200px;
        height: 200px;
        background-color: hotpink;
    }
    .one {
        background-color: green;
        width: 50px;
        height: 50px;
        margin-top: 100px;
    }
</style>
<body>
    <div class="container">
        <div class="one"></div>
    </div>
</body>

在这里插入图片描述
原本正确的显示方式,应该是粉色盒子与绿色盒子的顶部距离为50px,但是由于margin的塌陷问题,导致盒子内部的布局影响到了外部。这个时候,就可以触发BFC,将父盒子变成一个独立的区域,这样在BFC区域内部的任何操作,都不会影响到外部。

  .container{
        width: 200px;
        height: 200px;
        background-color: hotpink;
        overflow: hidden;
    }

在这里插入图片描述

5.3 自适应两栏布局
<style>
    * {
        margin: 0;
        padding: 0;
    }
    .left {
        float: left;
        background-color: green;
        width: 200px;
        height: 200px;
    }

    .right {
        overflow: hidden;
        height: 200px;
        background-color: hotpink;
    }
</style>
<body>
    <div class="container">
        <div class="left"></div>
        <div class="right"></div>
    </div>
</body>

在这里插入图片描述
right设置 overflow: hidden 创建BFC,因为BFC的区域不会与float box重叠,实现了自适应两栏布局

  • 10
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值