概述
说到BFC,其实刚开始我也很迷,翻看了一些文档后打算来 总结一下,首先,BFC其实就是一种布局,说到CSS布局,大抵也就是普通流、浮动(元素会脱离普通流)、定位(元素会脱离普通流),BFC也属于普通流,加了BFC样式的元素像是给元素加了个结界,结界内部的元素不会影响外面的元素,被隔离开了。
BFC规则
• BFC就是一个块级元素,块级元素会在垂直方向一个接一个的排列;
• BFC样式的元素像是给元素加了个结界,结界内部的元素不会影响外面的元素,被隔离开了;
• 垂直方向的距离由margin决定, 属于同一个BFC的两个相邻的标签外边距会发生重叠;
• 计算BFC的高度时,浮动元素也参与计算;
• BFC布局是可以通过一些条件触发的,从而实现布局上的需求或解决一些问题;
• BFC就是一个工具,知道其是什么且怎么用就好;
• BFC可以看做是一个CSS元素属性
BFC触发条件
• 根元素(<html>)
• float值非none,即left,right)
• overflow值非visible即hidden,auto,scroll
• display值为inline-block、table-cell、table-caption、table、table-row、table-row-group、table-header-group、table-footer-group、inline-table、flow-root、flex、inline-grid、inline-flex。
• position值为absolute、fixed
注意 :
1、并不是所有元素都是BFC,只有满足了BFC的条件后,此元素才成为了1个BFC。
2、一个BFC区域,只包含其所有子元素,不包含子元素的子元素,举个例子,爷爷只养儿子不养孙子,孙子是儿子负责。
举个例子:
<body>
<div class="test1"></div>
<div class="test2"></div>
<div class="test2">
<h1>hello</h1>
<h1>world!</h1>
</div>
</body>
上述代码,body元素算1个BFC,其子元素为test1,test2,但不包括test2里的两个h1标签,此时test2也不是BFC,因为不满足任何BFC条件。
要想test2成为一个BFC,给其设置为上述的任何一个条件即可
<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>
.test2 {
overflow: hidden;
}
</style>
</head>
<body>
<div class="test1"></div>
<div class="test2"></div>
<div class="test2">
<h1>hello</h1>
<h1>world!</h1>
</div>
</body>
</html>
BFC的应用场景
1、属于同一个BFC的两个相邻容器的上下margin会重叠
<html>
<head>
<style type="text/css">
.top {
width: 200px;
height: 200px;
background: red;
margin-bottom: 40px;
}
.bottom {
width: 200px;
height: 200px;
background: green;
margin-top: 60px;
}
</style>
</head>
<body>
<div class="top"></div>
<div class="bottom"></div>
</body>
</html>
效果图:
如图所示绿色盒子的上边距是60px,红色盒子的下边距是40px,会选取最大的60px。这种现象叫做margin塌陷。
原因:因为此时红盒子和绿盒子属于同一个BFC,也就是根元素(<html>),BFC的特性1规定“属于同一个BFC的两个相邻容器的上下margin会重叠,故两者上下边距发生重叠”
解决方案:
分离两个盒子,使它们处于不同的BFC就互不干涉了,给绿盒子加个div,其式样为overflow:hidden,分离BFC后就可以解决 margin重叠的问题了。
<html>
<head>
<style type="text/css">
.top {
width: 200px;
height: 200px;
background: red;
margin-bottom: 40px;
}
.bottom {
width: 200px;
height: 200px;
background: green;
margin-top: 60px;
}
.box {
overflow: hidden;
}
</style>
</head>
<body>
<div class="top"></div>
<div class="box">
<div class="bottom"></div>
</div>
</body>
</html>
2、计算BFC高度时浮动元素也参与计算
<html>
<head>
<style type="text/css">
.outside {
border: 10px solid blue;
}
.inside {
width: 200px;
height: 200px;
background: yellowgreen;
/* float: left; */
}
</style>
</head>
<body>
<div class="outside">
<div class="inside"></div>
</div>
</body>
</html>
我们先看下正常情况,有两个盒子(div)=》outside为父元素,inside为子元素。父元素的样式设置了边框,目的想包裹住子元素。
效果图:
下面我们把子元素设置浮动,脱离文档流。float:left;
<html>
<head>
<style type="text/css">
.outside {
border: 10px solid blue;
}
.inside {
width: 200px;
height: 200px;
background: yellowgreen;
float: left;
}
</style>
</head>
<body>
<div class="outside">
<div class="inside"></div>
</div>
</body>
</html>
效果图:
子元素设置了浮动,脱离了文档流,所以造成上图现象。
原因:父元素没有设置高度且子元素设置浮动的时候,父元素就会出现高度塌陷。
来我们看下给父元素设置高度是什么效果。
<html>
<head>
<style type="text/css">
.outside {
height: 200px;
border: 10px solid blue;
}
.inside {
width: 200px;
height: 200px;
background: yellowgreen;
float: left;
}
</style>
</head>
<body>
<div class="outside">
<div class="inside"></div>
</div>
</body>
</html>
解决方案:
要么给父元素添加高度,要么给父元素样式添加overflow:hidden。
<html>
<head>
<style type="text/css">
.outside {
overflow: hidden;
border: 10px solid blue;
}
.inside {
width: 200px;
height: 200px;
background: yellowgreen;
float: left;
}
</style>
</head>
<body>
<div class="outside">
<div class="inside"></div>
</div>
</body>
</html>
原因:给父元素添加样式overflow:hidden。父元素触发了BFC,BFC特性规定计算BFC高度时浮动元素也参与计算,这里子元素设置了浮动,因为BFC所以其高度仍计算到父元素内,从而解决了高度塌陷的问题。
3、BFC的区域不会与浮动容器发生重叠
两个相关的盒子,盒子1设置了左浮动,脱离了文档流,所以不会自适应两栏。两个盒子发生了重叠。
<html>
<head>
<style type="text/css">
.left {
width: 100px;
height: 200px;
background: yellowgreen;
float: left;
}
.right {
width: 300px;
height: 300px;
background: blue;
}
</style>
</head>
<body>
<div class="left"></div>
<div class="right"></div>
</body>
</html>
效果图:
解决方案:
给右侧元素设置样式overflow:hidden,使得右侧元素触发BFC,BFC特性规定:BFC的区域不会与浮动容器发生重叠,触发BFC解决重叠问题,实现自适应两栏效果。
<html>
<head>
<style type="text/css">
.left {
width: 100px;
height: 200px;
background: yellowgreen;
float: left;
}
.right {
width: 300px;
height: 300px;
overflow: hidden;
background: blue;
}
</style>
</head>
<body>
<div class="left"></div>
<div class="right"></div>
</body>
</html>
效果图:
4、BFC内的容器在垂直方向依次排列
类似正常情况下块元素在垂直方向上依次排列,较易理解。
5、BFC是独立容器,容器内部元素不会影响容器外部元素
(解决包含塌陷)
<head>
<style>
.father {
width: 300px;
height: 300px;
background-color: blueviolet;
}
.son {
width: 100px;
height: 100px;
background: burlywood;
margin-top: 50px;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
效果图:
原因:
父元素也跟着子元素的margin-top下移了50px;
解决方案:
设置父元素为一个BFC区域
<head>
<style>
.father {
width: 300px;
height: 300px;
background-color: blueviolet;
overflow: hidden;
}
.son {
width: 100px;
height: 100px;
background: burlywood;
margin-top: 50px;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
效果图:
7、使用BFC实现左侧盒子定宽,右侧盒子自适应布局
左侧设置为浮动,右侧也设置为浮动,右侧的宽度计算为100%-左侧
<style>
.left {
width: 300px;
height: 600px;
background-color: aqua;
float: left;
}
.right {
/* width: calc(100% - 300px); */
float: left;
height: 600px;
background-color: blueviolet;
}
</style>
</head>
<body>
<div class="left"></div>
<div class="right"></div>
</body>
不加BFC的效果图:
加了BFC的效果图:
补充知识点:
使用display属性能够将三者任意转换:
(1)display:inline;转换为行内元素
(2)display:block;转换为块状元素
(3)display:inline-block;转换为行内块状元素
① 行内元素:
(1)设置宽高无效
(2)对margin仅设置左右方向有效,上下无效;padding设置上下左右都有效,即会撑大空间
(3)不会自动进行换行
② 块状元素:
(1)能够识别宽高
(2)margin和padding的上下左右均对其有效
(3)可以自动换行
(4)多个块状元素标签写在一起,默认排列方式为从上至下
③行内块状元素特征:
(1)不自动换行
(2)能够识别宽高
(3)默认排列方式为从左到右
使用display属性能够将三者任意转换:
(1)display:inline;转换为行内元素
(2)display:block;转换为块状元素
(3)display:inline-block;转换为行内块状元素
参考文章:https://www.itcast.cn/news/20...
https://blog.csdn.net/leelxp/...