一、什么是BFC
首先介绍Box、 Formatting context的基本概念;
Box: Box 是 CSS 布局的对象和基本单位, 直观点来说,就是一个页面是由很多个 Box 组成的。元素的类型和 display 属性,决定了这个 Box 的类型。不同类型的 Box, 会参与不同的 Formatting Context,因此Box内的元素会以不同的方式渲染。
扩展:其他类型Box
- block-level box:display 属性为 block, list-item, table 的元素,会生成 block-level box。并满足 BFC;
- inline-level box:display 属性为 inline, inline-block, inline-table 的元素,会生成 inline-level box。并满足 IFC;
- run-in box :display 属性为 run-in 的元素,会生成 run-in box。(css3)具体内容见: https://codepen.io/wenjul/pen/OXReza;
Formatting context : 它是 W3C CSS2.1 规范中的一个概念。是页面中的一块渲染区域,有一套渲染规则,决定了其子元素如何布局,以及和其他元素之间的关系和作用。最常见的 Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context (简称IFC)。 而在CSS3中,新增了 GFC 和 FFC。
BFC 即 Block formatting context (块级格式化上下文);
扩展:其他三种FC
- IFC (Inline Formatting Contexts)直译为"内联格式化上下文".
- GFC(GridLayout Formatting Contexts)直译为"网格布局格式化上下文"。display值为grid时.
- FFC(Flex Formatting Contexts)直译为"自适应格式化上下文",display值为flex或者inline-flex的时.
后续会继续分享其他几种FC类型。
二、BFC触发条件。
- 根元素. 即HTML元素.
- float 不为 none 时.
- overflow 不为 visible时.
- display 为 inline-block、table-cell、table-caption.
- position 为 absolute 或 fixed.
三丶BFC布局规则
- 内部BOX会在垂直方向, 一个接一个地放置.
- Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
- 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- BFC的区域不会与float box重叠。
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算BFC的高度时,浮动元素也参与计算
四、BFC的作用及案例。
- 清除文字环绕,两栏布局
- 清除浮动
- 防止垂直margin重叠
1)清除文字环绕,两栏布局
页面布局:
这里满足 BFC布局规则第三条:每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
代码:
<style>
* {
margin: 0;
padding: 0;
}
.layout {
width: 200px;
}
.layout .left {
float: left;
width: 100px;
height: 150px;
background-color: red;
}
.layout .right {
height: 200px;
background-color: green;
}
</style>
</head>
<body>
<section class="layout">
<div class="left">
左边栏
</div>
<div class="right">
我是右边栏我是右边栏我是右边栏我是右边栏我是右边栏我是右边栏我是右边栏我是右边栏我是右边栏我是右边栏我是右边栏我是右边栏
</div>
</section>
可以看到, 左边栏float生效,使得左边栏悬浮在layout里, 其中layout部分被覆盖,但文字却悬浮在左边栏周围,没有被覆盖。这是因为float在设计时就是为了使文本围绕在浮动对象的周围. 这时我们要实现取消文字环绕并实现两栏布局,只需要使得右边栏变成BFC(当然也可以为左边栏添加外边距取消文字环绕)
添加代码:
.layout .right{
overflow: hidden;
}
结果:
这里满足 BFC布局规则第四条:BFC
的区域不会与float box
重叠。
2)清除浮动
当一个盒子内的子元素浮动时,子元素脱离文档流,使得父元素无高度。解决方法可以用常用的伪元素:after解决,也可以用BFC解决。
页面布局:
代码:
<style>
*{
margin: 0;
padding: 0;
}
.float {
width: 300px;
border: 3px solid red;
}
.float .item{
float: left;
width: 100px;
height: 100px;
border: 4px solid #000;
box-sizing: border-box;
}
</style>
</head>
<body>
<section class="float">
<div class="item"></div>
<div class="item"></div>
</section>
</body>
我们可以为float类生成BFC,利用 BFC布局规则第六条: 计算BFC的高度时,浮动元素也参与计算.
即添加代码:
.float {
overflow: hidden;
}
3)防止垂直margin重叠
在CSS当中,相邻的两个盒子(可以是兄弟、祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。
折叠的结果:
-
两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
-
两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
-
两个外边距一正一负时,折叠结果是两者的相加的和。
页面布局:
代码:
<style>
* {
margin: 0;
padding: 0;
}
.margin {
width: 200px;
border: 2px solid #000;
}
.margin p{
background-color: red;
padding: 10px;
text-align: center;
color: #fff;
}
.margin .top {
margin-bottom: 40px;
}
.margin .bom {
margin-top: 40px;
}
</style>
</head>
<body>
<section class="margin">
<p class="top">上</p>
<p class="bom">下</p>
</section>
</body>
这里将上下边距设置为40px,但因为发生边距折叠,只显示40px边距。
具体折叠情况:
这里可以利用 BFC布局规则第二条: Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠.
故可以使得两个P标签不属于同一个BFC。
情况如下图:
给top类外套一个div,并生成一个BFC.
<section class="margin">
<div class="top_wrap">
<p class="top">上</p>
</div>
<p class="bom">下</p>
</section>
.margin .top_wrap {
overflow: hidden;
}
还有一种方法是改变display,但是会导致样式丢失。这里就不细讲了。
参考资料:
https://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html
http://www.w3cplus.com/css/understanding-bfc-and-margin-collapse.html