浅析什么是BFC、BFC的层叠规则、怎样触发BFC及BFC主要解决了什么问题、清除浮动的6种方式
一、BFC 知识
1、BFC 是什么?
BFC 全称:Block Formatting Context
, 名为 "块级格式化上下文"。
W3C官方解释为:BFC 它决定了元素如何对其内容进行定位,以及与其它元素的关系和相互作用。当涉及到可视化布局时,Block Formatting Context
提供了一个环境,HTML 在这个环境中按照一定的规则进行布局。
浮动定位和清除浮动的时候只会应用于同一个BFC内的元素。浮动不会影响其他BFC中元素的布局,而清除浮动只能清除同一BFC中在它前面的元素的浮动
外边距的折叠也只会发生在同一BFC中的块级元素之间,可以创建新的BFC来消除外边距的折叠问题。
常见的定位布局方案有:普通流,浮动和绝对定位
BFC 是一块渲染区域,有一套渲染定位规则。决定子元素定位其他元素的关系和相互作用,是属于普通流的。具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性。其实也不是什么新鲜东西,可能都在用但不知道这个概念
简单来说就是:
BFC 是一个完全独立的空间(布局环境),让空间里的子元素不会影响到外面的布局。那么怎么使用BFC呢?BFC可以看做是一个css元素属性
2、怎样触发 BFC?
简单列举几个触发BFC使用的css属性:
(1)overflow: hidden; 只要不是 visible 就可以
(2)position: absolute; 或 fixed 绝对定位的元素(即不是 relative 或 static)
(3)display: flex; 或 inline-block; inline-flex; table; table-cell; 等
(4)float: left; 浮动元素(即float不为none)
整理到这儿,对于上面第3条产生了一个疑问:为什么display: inline-block;
的元素是inline level
的元素,参与形成IFC,却能创建BFC?后来觉得答案是这样的:inline-block的元素的内部是一个BFC,但是它本身可以和其它inline元素一起形成IFC
- BFC 就是一个块级元素,块级元素的内部会在垂直方向一个接一个的排列
- BFC 就是页面中的一个隔离的独立容器,容器里的标签不会影响到外部标签
- BFC的区域不会与 float box重叠
- 垂直方向的距离由margin决定, 属于同一个BFC的两个相邻的标签外边距会发生重叠
- BFC里面的box元素在水平方向的左边缘会与BFC的左边缘相对齐
- 计算BFC的高度时,浮动元素也参与计算
二、BFC 主要解决了什么问题
<div class="container">
<div class="box"></div>
<div class="box"></div>
</div>
.box {
margin: 100px;
width: 100px;
height: 100px;
background: red;
float: left;
}
.container {
background: #000;
}
上面给box
设置完float
结果脱离文档流,使container
高度没有被撑开,高度为0。
解决此问题可以给container
触发BFC
,上面我们所说到的触发BFC
属性都可以设置(其他属性都是可以的,可以自己试下)
2、margin 边距重叠
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
margin: 10px;
width: 100px;
height: 100px;
background: #000;
}
</style>
</head>
<body>
<div class="container">
<div class="box"></div>
<div class="box"></div>
</div>
</body>
</html>
可以看到上面我们为两个盒子的margin
外边距设置的是10px
,可结果显示两个盒子之间只有10px
的距离,这就导致了margin
塌陷问题,这时margin
边距的结果为最大值,而不是合,为了解决此问题可以使用BFC
规则(为元素包裹一个盒子形成一个完全独立的空间,做到里面元素不受外面布局影响)
解决:加个 overflow: hidden; 即可,也可以试别的属性
总结一下核心思想就是这这两个节点不在同一个BFC下
3、float 元素的影响,比如解决两栏布局
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>两栏布局</title>
<style>
div {
width: 200px;
height: 100px;
border: 1px solid red;
}
</style>
</head>
<body>
<div style="float: left;">
两栏布局两栏布局两栏布局两栏布局两栏布局两栏布局两栏布局两栏布局两栏布局两栏布局两栏布局两栏布局两栏布局
</div>
<div style="width: 300px;">
我是蛙人,如有帮助请点个赞叭,如有帮助请点个赞叭,如有帮助请点个赞叭,如有帮助请点个赞叭,如有帮助请点个赞叭,如有帮助请点个赞叭
</div>
</body>
</html>
现象:可以看到上面元素,第二个div
元素为300px
宽度,但是被第一个div
元素设置Float
脱离文档流给覆盖上去了
(1)你float我也float,block-2里面设定float: left
,那么block-2也自动形成了BFC,它不会和浮动元素重叠
(2)overflow: hidden
思路也和上面差不多。解决此方法我们可以把第二个div
元素设置为一个BFC
从上面的规则:BFC 不会与 float box 区域重合;以及BFC是隔离容器,里面的元素不会对外面产生影响,反指亦然。故使用 BFC 可以解决这个问题
对于两栏布局,多说一句其实最好是用flex或者grid来解决,但是这些比较经典的问题还是要熟悉熟悉
总结一下:边距折叠、清除浮动、多栏布局,这几个可以说是BFC的要点了
三、清除浮动的6种方式
比较老古董的技术了,了解一下即可,看这篇文章:https://juejin.cn/post/6982179919597928485