一篇文章弄懂BFC

一、什么是BFC?

借鉴了文章 👉 面试官:谈谈你对BFC的理解?

我们在页面布局的时候,经常出现以下情况:

这个元素高度怎么没了?
这两栏布局怎么没法自适应?
这两个元素的间距怎么有点奇怪的样子?

原因是元素之间相互的影响,导致了意料之外的情况,这里就涉及到了 BFC 概念 :

BFC(Block Formatting Context),即块级格式化上下文,它是页面中的一块渲染区域,并且有一套属于自己的渲染规则(前三条规则仅针对于非BFC元素):

  • 内部的盒子会在垂直方向上一个接一个的放置;
  • 对于同一个BFC下的两个上下相邻盒子的 上下外边距 (margin) 会发生重叠
  • 每个元素的左外边距与包含块的左边界相接触( 即BFC中子元素不会超出他的包含块 ),即使浮动元素也是如此;
  • BFC的区域不会与浮动的元素区域重叠
  • 计算BFC的高度时,浮动子元素也参与计算

BFC 的目的是形成一个相对于外界完全独立的空间,让内部的子元素不会影响到外部的元素,反之亦然


下面我们来直观的演示一下BFC的渲染规则:

  1. 内部的盒子会在垂直方向上一个接一个的放置

    一个简单的代码示例:

    <style>
    	body {
    		width: 300px;
    	}
    
    	.BFC {
    		overflow: hidden;
    	}
    
    	.aside,
    	.aside2 {
    		width: 100px;
    		height: 150px;
    		background: #f66;
    	}
    
    	.aside2 {
    		background-color: rgb(16, 171, 176);
    	}
    
    	.main {
    		height: 200px;
    		background: #fcc;
    	}
    </style>
    
    <body>
    	<div class="BFC">
    		<div class="aside"></div>
    		<div class="aside2"></div>
    		<div class="main"></div>
    	</div>
    </body>
    
    效果图,BFC里面的元素依次垂直排列:

    在这里插入图片描述


  1. 对于同一个BFC下的两个上下相邻盒子的 上下外边距 (margin) 会发生重叠

    我们在上一个代码的基础上,为 asideaside2 分别增加了上边距和下边距:

    	.aside {
    		margin-bottom: 30px;
    	}
    	
    	.aside2 {
    		margin-top: 30px;
    	}
    

    理想效果应该是 asideaside2 之间的间距为 60px,下面是实际效果图:

    下面这张图是 aside 的下外边距:

    在这里插入图片描述

    下面这张图是 aside2 的上外边距:

    在这里插入图片描述
    可以清楚地看到,他们的外边距发生了重叠,且重叠后的高度为30px在这里插入图片描述

    那看官可能又会有一个疑问:如果一个外边距是 40px ,另一个外边距是 30px 呢?
    答案是:外边距重叠后的总外边距,以外边距更大的一方为准; 看官可以自己实验一下;


为什么重叠现象只会发生在上下相邻的盒子,并且只有上外边距和下外边距会发生重叠?
①因为 display:block; 不会触发BFC,所以只有块状元素会发生外边距重叠现象,而行内元素和行内块元素均会触发BFC!
②块状元素默认独占一行,所以只会出现上下相邻的现象,如果通过浮动让其排列在同一行,则又会触发BFC!

  1. 每个元素的左外边距与包含块的左边界相接触( 即BFC中子元素不会超出他的包含块 ),即使浮动元素也是如此

    下面的代码在上述代码的基础上为 asideaside2 添加了左浮动,完整代码示例:

    <style>
    	body {
    		width: 300px;
    	}
    
    	.BFC {
    		overflow: hidden;
    	}
    
    	.aside,
    	.aside2 {
    		float: left;
    		width: 100px;
    		height: 150px;
    		background: #f66;
    	}
    
    	.aside2 {
    		background-color: rgb(16, 171, 176);
    	}
    
    	.main {
    		height: 200px;
    		background: #fcc;
    	}
    </style>
    
    <body>
    	<div class="BFC">
    		<div class="aside"></div>
    		<div class="aside2"></div>
    		<div class="main"></div>
    	</div>
    </body>
    

    实际效果图:

    在这里插入图片描述

    由于float元素脱离了标准流,所以 main 盒子和浮动元素的区域发生了重叠,但它们都没有超出它们的包含块;


  1. BFC的区域不会与浮动的元素区域重叠

    这一渲染规则刚好可以解决上面的问题,只需要为 main 盒子添加 overflow:hidden; 使其成为BFC元素就可以解决与浮动元素的区域重叠的问题:

    	.main {
    		overflow: hidden;
    		height: 200px;
    		background: #fcc;
    	}
    
    效果图:

    在这里插入图片描述


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

    非常的简单,即清除浮动造成的影响,代码示例:

    <style>
        .par {
        	width: 300px;
            border: 5px solid #fcc;
        }
     
        .child {
            float: left;
            width:100px;
            height: 100px;
            border: 5px solid #f66;
        }
    </style>
    <body>
        <div class="par">
            <div class="child"></div>
            <div class="child"></div>
        </div>
    </body>
    

    页面显示如下:
    par没有高度
    最外面的盒子 par 没有高度两个浮动的子元素没有参与高度计算

    要想让par获得高度,只要让它触发BFC就好了

    .par {
        overflow: hidden;
    }
    
    效果如下:

    在这里插入图片描述


二、BFC的触发条件:

触发BFC的条件包含不限于:

  1. 根元素,即 <html> 元素
  2. 浮动元素:float值 不为 none
  3. overflow值不为 visible,为 auto、scroll、hidden
  4. display的值为 inline-block、 inltable-cell、 table-caption、 table、 inline-table、 flex、 inline-flex、 grid、 inline-grid
  5. position的值为 absolute 或 fixed

三、BFC的应用场景:

利用 BFC 的渲染规则的特性,我们将 BFC 应用在以下场景:

1. 防止margin重叠(塌陷)
<style>
    p {
    	margin: 100px;
    	width: 200px;
        color: #f55;
        background: #fcc;
        line-height: 100px;
        text-align:center;
    }
</style>
<body>
    <p>Haha</p >
    <p>Hehe</p >
</body>
页面显示如下:

来自面试官
两个 p 元素之间的距离为100px,发生了margin重叠(塌陷),且重叠后的总外边距以最大的为准,如果第一个 p 的 margin 为 80px 的话,两个 p 之间的距离还是100;

那么我们可以在 p 外面包裹一层容器,并触发这个容器生成一个BFC,那么两个 p 就不属于同一个BFC,则不会出现 margin 重叠:

<style>
	.wrap {
        overflow: hidden;// 新的BFC
      }
      
    p {
    	margin: 100px;
    	width: 200px;
        color: #f55;
        background: #fcc;
        line-height: 100px;
        text-align:center;
    }
</style>
<body>
    <p>Haha</p >
    <div class="wrap">
        <p>Hehe</p >
    </div>
</body>

2. 清除内部浮动影响
<style>
    .par {
    	width: 300px;
        border: 5px solid #fcc;
    }
 
    .child {
        float: left;
        width:100px;
        height: 100px;
        border: 5px solid #f66;
    }
</style>
<body>
    <div class="par">
        <div class="child"></div>
        <div class="child"></div>
    </div>
</body>

页面显示如下:
par没有高度
最外面的盒子 par 没有高度两个浮动的子元素没有参与高度计算

要想让par获得高度,只要让它触发BFC就好了

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

.par {
    overflow: hidden;
}

效果如下:

在这里插入图片描述


3. 自适应多栏布局(或者说解决浮动元素覆盖盒子区域的问题)

这里的举例为两栏布局

<style>
	body {
		width: 300px;
	}

	.aside,
	.aside2 {
		float: left;
		width: 100px;
		height: 150px;
		background: #f66;
	}

	.aside2 {
		background-color: rgb(16, 171, 176);
	}

	.main {
		height: 200px;
		background: #fcc;
	}
</style>

<body>
	<div class="aside"></div>
	<div class="aside2"></div>
	<div class="main"></div>
</body>

效果图如下:

在这里插入图片描述

前面讲到,BFC 中的每个元素的左外边距与包含块的左边界相接触,并且由于 .aside.aside2 为浮动元素,所以 main 区域与 .aside2 区域发生了重叠

但是 BFC 的区域不会与浮动盒子重叠

所以我们可以通过触发 main 生成 一个新的BFC, 以此适应两栏布局

.main {
    overflow: hidden;
}

这时候,新的 BFC 不会与浮动的 .aside 元素重叠

因此 main 会根据包含块的宽度,和 .aside 的宽度,自动变窄

效果如下:

在这里插入图片描述

可以看到,上面几个案例都体现了BFC实际就是页面一个独立的容器,里面的子元素不影响外面的元素,外面的元素也不会影响到里面的子元素;

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值