一文带你彻底弄懂BFC

先说说FC,FC的含义就是Fomatting Context。它是CSS2.1规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。

BFC和IFC都是常见的FC。分别叫做Block Fomatting Context 和Inline Formatting Context。

BFC(Block Formatting Context)叫做“块级格式化上下文”。

BFC的布局规则

1.内部的盒子会在垂直方向,一个个地放置;

2.盒子垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的上下margin会发生重叠。垂直方向上的距离会叠加,值由最大margin值决定(如果不要叠加,就需要将该盒子变成一个独立的盒子)

3.每个元素的左边,与包含的盒子的左边相接触,即使存在浮动也是如此;

4.BFC的区域不会与float重叠;

5.BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此;

6.计算BFC的高度时,浮动元素也参与计算。

形成BFC的条件

  • 根元素(即body);

  • 浮动元素,float的属性不为none;

  • 定位元素,position为absolute或fixed;

  • display为inline-block,table-cell,table-caption,flex;

  • overflow不为visible。(值为hidden/auto/scroll时)

BFC的作用

  • 解决margin重叠的问题(添加独立BFC)

  • 解决浮动高度塌陷的问题(在父级添加overflow:hidden)

  • 解决侵占浮动元素的问题(添加overflow:hidden清除浮动)

BFC特性详解

接下来我将用例子一一对其特性进行说明。

特性一

内部的盒子会在垂直方向,一个个地放置。

这个很好理解,body本身就是一个BFC,根据块级元素的定义,块级元素是会占满一整行的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BFC</title>
    <style>
        .container {
            width300px;
            border1px solid #000;

            /*触发BFC*/
            overflow: hidden;
            height400px;
        }

        .box1 {
            height20px;
            width50%;
            background-color: blue;
        }

        .box2 {
            height20px;
            width50%;
            background-color: yellow;
        }

    
</style>
</head>
<body>
<div class="container">
    <div class="box1"></div>
    <div class="box2"></div>


</div>
</body>
</html>
一文带你彻底弄懂BFC
img


特性二

盒子垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的上下margin会发生重叠。垂直方向上的距离会叠加,值由最大margin值决定(如果不要叠加,就需要将该盒子变成一个独立的盒子)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BFC</title>
    <style>
        .container {
            width300px;
            border1px solid #000;

            /*触发BFC*/
            overflow: hidden;
            height400px;
        }

        .box1{
            height20px;
            margin50px 0;
            background-color: blue;
        }

        .box2{
            height20px;
            margin60px 0;
            background-color: yellow;
        }

    
</style>
</head>
<body>
<div class="container">
    <div class="box1"></div>
    <div class="box2"></div>
</div>
</body>
</html>
一文带你彻底弄懂BFC
img

如果希望这两个盒子之间的margin不要重叠,则需要使其中一个盒子形成一个独立容器,即触发BFC。

这也是利用了BFC的第五个特性。

  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BFC</title>
    <style>
        .container {
            width300px;
            border1px solid #000;

            /*触发BFC*/
            overflow: hidden;
            height400px;
        }

        .wrapper {
            width100%;
            overflow: hidden;
            border2px solid purple;
        }

        .box1 {
            height20px;
            margin50px 0;
            background-color: blue;

        }

        .box2 {
            height20px;
            margin60px 0;
            background-color: yellow;
        }

    
</style>
</head>
<body>
<div class="container">
    <div class="box1"></div>
    <div class="wrapper">
        <div class="box2"></div>
    </div>


</div>
</body>
</html>
一文带你彻底弄懂BFC
img


特性三

3、每个元素的左边,与包含的盒子的左边相接触,即使存在浮动也是如此;

第三点也很好理解,就拿body来说,文档流都是从左往右排版的。即使存在浮动元素,BFC中其他元素的margin box的左边也会与包含块border box的左边相接触 。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            background: gray;
        }

        .left {
            /* 即使存在浮动元素,BFC中其他元素的margin box的左边也会与包含块border box的左边相接触 */
            /* 在这个例子中,黄框向左浮动,脱离了普通流,此时绿框被定位到包含块的左上角 */
            float: left;
            width100px;
            height80px;
            background: yellow;
            opacity: .5;
        }

        .right {
            width200px;
            height50px;
            background: green;
            opacity: .5;
        }
    
</style>
</head>
<body>
<div class='box'>
    <div class="left"></div>
    <div class="right"></div>
</div>

</body>
</html>
一文带你彻底弄懂BFC
img


特性四

BFC的区域不会与float重叠;

现有如下代码,左盒子设置成浮动,右边是普通的块级div。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BFC</title>
    <style>
        .box1 {
            /*浮动触发bfc*/
            float: left;
            width200px;
            height200px;
            background-color: blue;
            text-align: right;
        }

        .box2 {

            width500px;

            height300px;
            background-color: yellow;
        }

    
</style>
</head>
<body>

<div class="box1">右侧文字</div>
<div class="box2">左侧文字</div>

</body>
</html>

效果如图,左盒子由于被设置成向左浮动,触发了BFC,而右盒子未触发BFC,有部分区域被覆盖了。

一文带你彻底弄懂BFC
img

现在将右盒子也触发BFC。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BFC</title>
    <style>
        .box1 {
            /*浮动触发bfc*/
            float: left;
            width200px;
            height200px;
            background-color: blue;
            text-align: right;
        }

        .box2 {
            /*overflow触发bfc, 这里用float:left也行*/  
            overflow: hidden;
            width500px;
            height300px;
            background-color: yellow;
        }

    
</style>
</head>
<body>

<div class="box1">右侧文字</div>
<div class="box2">左侧文字</div>

</body>
</html>

效果如下。

一文带你彻底弄懂BFC
img


特性五

BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BFC</title>
    <style>
        .container01 {
            /*触发父盒子bfc*/
            float: left;
            width600px;
            border2px solid black;
            /*    高度靠内容撑开*/
        }

        .container02{
            /*触发父盒子bfc*/
            float: left;
            width600px;
            border2px solid black;
        }

        .box1 {
            /*浮动触发bfc*/
            float: left;
            width1000px;
            height200px;
            background-color: blue;
        }
        .box2 {
            /*浮动触发bfc*/
            float: left;
            width1000px;
            height200px;
            background-color: yellow;
        }



    
</style>
</head>
<body>
<div class="container01">
    <div class="box1">内容</div>
</div>
<div class="container02">
    <div class="box2">内容</div>
</div>

</body>
</html>

效果如图,左右盒子互不干涉。

一文带你彻底弄懂BFC
img

特性六

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

这个就是常见的去浮动的原理,触发BFC,面试中经常会问到的。

现有如下代码。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BFC</title>
    <style>
        .container {
            width600px;
            border2px solid black;
            /*    高度靠内容撑开*/
        }

        .box1 {
            /*浮动触发bfc*/
            float: left;
            width200px;
            height200px;
            background-color: blue;
        }


    
</style>
</head>
<body>
<div class="container">
    <div class="box1">内容</div>
</div>

</body>
</html>

效果如下图,可以看到,由于子盒子的浮动,父盒子的高度未被子盒子撑开,因而塌陷了。

一文带你彻底弄懂BFC
img

这时触发父元素形成BFC,就会将浮动元素的高度也计算入内了。

 .container {
            /*触发父盒子bfc*/
            overflow: hidden;
            width600px;
            border2px solid black;
            /*    高度靠内容撑开*/
}
一文带你彻底弄懂BFC
img



BFC应用场景

自适应两栏布局

现有如下代码,想要实现一个自适应的两栏布局。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        div {
            width300px;
        }

        .aside {
            width100px;
            height150px;
            float: left;
            background: black;
        }

        .main {
            height:200px;
            background-color:red;
        }
    
</style>
</head>
<body>
<div class="aside"></div>
<div class="main"></div>
</body>
</html>

效果如图。

一文带你彻底弄懂BFC
img

现在想要将黑色区域和红色区域分开来,不允许有重叠。

因为body本身就是一个BFC,这满足了规范的第三条:

  • 每个元素的左边,与包含的盒子的左边相接触,即使存在浮动也是如此。

所以如果我们需要将黑色区域撑到红色的左边,就需要利用规范的第四条:

  • BFC的区域不会与float重叠。

也就是说我们需要创造BFC区域。可以通过将红色区域的overflow设为hidden来触发BFC:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        div {
            width300px;
        }

        .aside {
            width100px;
            height150px;
            float: left;
            background: black;
        }

        .main {
            /*形成BFC*/
            overflow:hidden;

            height:200px;
            background-color:red;
        }
    
</style>
</head>
<body>
<div class="aside"></div>
<div class="main"></div>
</body>
</html>
一文带你彻底弄懂BFC
img


清除浮动

现有如下代码。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BFC</title>
    <style>
        .container {
            width600px;
            border2px solid black;
            /*    高度靠内容撑开*/
        }

        .box1 {
            /*浮动触发bfc*/
            float: left;
            width200px;
            height200px;
            background-color: blue;
        }


    
</style>
</head>
<body>
<div class="container">
    <div class="box1">内容</div>
</div>

</body>
</html>

效果如下图,可以看到,由于子盒子的浮动,父盒子的高度未被子盒子撑开,因而塌陷了。

一文带你彻底弄懂BFC
img

这时触发父元素形成BFC,就会将浮动元素的高度也计算入内了。

 .container {
            /*触发父盒子bfc*/
            overflow: hidden;
            width600px;
            border2px solid black;
            /*    高度靠内容撑开*/
}
一文带你彻底弄懂BFC
img

margin重叠

先定义两个垂直的div:

<div class="p"></div>
<div class="p"></div>

然后定义margin:

.p {
    width:200px;
    height:50px;
    margin:50px 0;
    background-color:red;
}

可以看到margin重叠后的效果:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .p {
            width200px;
            height50px;
            margin50px 0;
            background-color: red;
        }
    
</style>
</head>

<body>
<div class="p"></div>
<div class="p"></div>
</body>
</html>
一文带你彻底弄懂BFC
img

再看看BFC规范的第二条:

  • 盒子垂直方向的距离由margin决定,属于用一个BFC的两个相邻Box的上下margin会发生重叠。

说明两者属于同一个BFC,所以我们需要两个div不属于同一个BFC。
为第二个div套一个父亲div,然后将其overflow设为hidden来激活一个BFC就可以使margin不再重叠。

<div class="p"></div>
<div class="wrap">
    <div class="p"></div>
</div>
.wrap {
    overflow:hidden;
}

最终效果如下。

一文带你彻底弄懂BFC
img


原文始发于微信公众号(豆子前端):一文带你彻底弄懂BFC

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/56930.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!