CSS 中很重要的一环就是 BFC 块级格式化上下文,本文整理了 CSS BFC 的相关知识,建议沐浴更衣后食用。
在正式讲解BFC之前,先了解一下浏览器外边距重叠的问题。
MDN:块的上外边距(margin-top)和下外边距(margin-bottom)有时合并(折叠)为单个边距,其大小为单个边距的最大值(或如果它们相等,则仅为其中一个),这种行为称为边距折叠。
注意:外边距重叠都是发生在块级元素中,设定 float 和 position=absolute 的元素不会产生外边距重叠行为。
有三种情况会形成外边距重叠:
<style>
div {
width: 100px;
height: 100px;
background-color: pink;
}
.box1{
margin-bottom: 100px;
}
.box2{
margin-top: 200px;
}
style>
<div class="box1">div>
<div class="box2">div>
<style>
.wrapper {
width: 200px;
height: 200px;
background-color: pink;
}
.box{
width: 100px;
height: 100px;
margin-top: 100px;
background-color: powderblue;
}
style>
<div class="wrapper">
<div class="box">div>
div>
<style>
div {
margin-top: 100px;
margin-bottom: 200px;
}
style>
<p>内容1p>
<div>div>
<p>内容2p>
各行内框(inline boxes)一个接一个地排列,其排列顺序根据书写模式的设置来决定:
.horizontal {
writing-mode: horizontal-tb; // 从左开始
}
.vertical {
writing-mode: vertical-rl; // 从上开始
}
块格式化上下文(Block Formatting Context,BFC) 是 Web 页面的可视 CSS 渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。形成独立的渲染区域,内部元素的渲染不会影响外界。
总结来说具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性。
注意:很多博客都会将属于同一个BFC的两个相邻盒子的margin会发生重叠
认为是BFC的特性,不是!不是!没有触发 BFC 也是如此排列的。BFC 可以解决这种重叠,但对于margin重叠,我们通常不解决,合理利用就好了。
内部的盒子会在垂直方向上一个接一个的放置,垂直方向上的距离由margin决定。BFC可以避免margin折叠,例子:
<style>
.wrapper{
border: 1px solid black;
}
.box {
width: 200px;
height: 200px;
background-color: #999;
}
.box1 {
margin-bottom: 100px;
}
.box2 {
margin-top: 200px;
}
style>
<div class="wrapper">
<div class="box1 box">div>
<div class="box2 box">div>
div>
如下图,在普通文档流中,两个相邻容器的上下margin会重叠,并且取其最大的margin。
如果让其中一个盒子处于独立的BFC中,就不会重叠。如下图
<style>
.wrapper{
border: 1px solid black;
}
.wrapper2{
overflow: hidden;
}
.box {
width: 200px;
height: 200px;
background-color: #999;
}
.box1 {
margin-bottom: 100px;
}
.box2 {
margin-top: 200px;
}
style>
<div class="wrapper">
<div class="wrapper2">
<div class="box1 box">div>
div>
<div class="box2 box">div>
div>
<style>
.wrapper{
width: 200px;
height: 200px;
background: powderblue;
overflow: hidden;
}
.box{
width: 100px;
height: 100px;
margin-top: 100px;
background: pink;
}
style>
<div class="wrapper">
<div class="box">div>
div>
下图1为没有触发BFC,box的margin-top溢出到父元素。下图2为触发了BFC,内部的元素不会影响外部。
计算BFC的高度时,浮动元素也参与计算。可以用此撑开父元素。
<style>
.wrapper{
border: 1px solid black;
}
.box{
width: 100px;
height: 100px;
background: pink;
float: left;
}
style>
<div class="wrapper">
<div class="box">div>
div>
因为浮动会脱离普通流,形成浮动流,所以父级高度不会被子元素撑开。如下图
当触发BFC时,float元素会计入高度的计算中。
<style>
.wrapper{
border: 1px solid black;
overflow: hidden;
}
.box{
width: 100px;
height: 100px;
background: pink;
float: left;
}
style>
<div class="wrapper">
<div class="box">div>
div>
BFC的区域不会与float的元素区域重叠。所以可以用来清除浮动
<style>
.box1{
width: 100px;
height: 100px;
background: pink;
float: left;
}
.box2{
width: 200px;
height: 200px;
background: powderblue;
}
style>
<div class="box1">div>
<div class="box2">div>
结果如下图,可以看到,box2会和box1重叠出现。
当我们触发BFC之后,可以看到下图,并不会与float重叠
<style>
.box1{
width: 100px;
height: 100px;
background: pink;
float: left;
}
.box2{
width: 200px;
height: 200px;
background: powderblue;
overflow: hidden;
}
style>
<div class="box1">div>
<div class="box2">div>
<style>
.left{
width: 100px;
height: 100px;
background: pink;
float: left;
}
.right{
height: 100px;
background: powderblue;
overflow: hidden;
}
style>
<div class="left">div>
<div class="right">div>
<style>
.left {
width: 100px;
height: 100px;
float: left;
background: #ffc0cb;
}
.right {
width: 100px;
height: 100px;
float: right;
background: #ffc0cb;
}
.center{
height: 100px;
background: powderblue;
overflow: hidden;
}
style>
<div class="left">div>
<div class="right">div>
<div class="center">div>
没啥卵用,但是这是一个用处。
<style>
.left {
width: 100px;
height: 100px;
background: #ffc0cb;
float: left;
}
p{
width: 200px;
background: powderblue;
overflow: hidden;
}
style>
<div class="left">div>
<p>
你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界你好世界
p>
我们经常用 float 来实现文字环绕的报纸效果,但如果你不想环绕…就可以触发 BFC 实现
希望对大家有用,记得点赞关注哦~