持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情
FC -- Formatting Context
元素在标准流里面都是属于一个FC的:可能是block,也可能是inline。
Block-level boxes 属于BFC,inline-level boxes属于IFC
BFC -- Block Formatting Context
BFC的作用:
- 在BFC中,box会在垂直方向上一个挨着一个的排布;
- 垂直方向的间距由margin属性决定;
- 在同一个BFC中,相邻两个box之间的margin会折叠
- 在BFC中,每个元素的左边缘是紧挨着包含块的左边缘的;
<style>
* {
padding: 0;
margin: 0;
}
.item {
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
width: 50%;
height: 100px;
border: 1px solid red;
}
.item:nth-child(odd) {
background-color: #ccc;
}
</style>
</head>
<body>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</body>
为什么我们创建了五个div标签,他们会成这样排布呢?也就是为什么会什么会成竖直排布,他们会什么会紧挨着一起,他们为什么会排列在浏览器的左边呢?
这就是因为他们属于一个BFC里,他们都属于在html这个BFC里。所以在这个BFC里的所有box都会遵守上面的四条准则。
margin折叠
我们来看一个margin折叠问题
<style>
* {
padding: 0;
margin: 0;
}
.item {
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
width: 50%;
height: 100px;
border: 1px solid red;
}
.item:nth-child(2) {
background-color: #ccc;
margin-top: 50px;
}
.item:nth-child(1) {
background-color: #000;
margin-bottom: 20px;
color: #fff;
}
</style>
</head>
<body>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</body>
这里我们的第一个item的margin-bottom为20px,第二个item的margin-top为50px;按理来说,他们之间的距离应该有70px,但是真实结果呢?
我们发现第二个item的height为102px(height+margin-top+border),但是它是紧挨着第一个item的,按理来说他们应该还有着20px的距离。但是并没有。
结果就是: 在同一个BFC里,两个box之间如果有margin的话,那么他们之间总的margin取的是大的那一个,并不会两两相家。
那么如何解决呢?当然是靠BFC咯。
<style>
* {
padding: 0;
margin: 0;
}
.item {
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
width: 50%;
height: 100px;
border: 1px solid red;
}
.item:nth-child(2) {
background-color: #ccc;
margin-top: 50px;
}
.item:nth-child(1) {
background-color: #000;
margin-bottom: 20px;
color: #fff;
}
.father {
overflow: auto;
}
</style>
</head>
<body>
<div class="father">
<div class="item">1</div>
</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</body>
结果:
原因: 我们给第一个item外层嵌套一个div,这个div设置了一个属性overflow:auto;,这样就给.father这个div创造了一个新的BFC,这样第一个item个第二个item就没有在同一个BFC里了,他们就不会再发生margin合并了。
注:这个属性不一定要overflow:auto;看最上面我发的那张图,那些属性都可以创建一个新的BFC。
利用BFC解决浮动的高度塌陷问题
<style>
* {
padding: 0;
margin: 0;
}
.container {
background-color: orange;
}
.item {
float: left;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
width: 10%;
height: 100px;
border: 1px solid red;
}
.item:nth-child(odd) {
background-color: #ccc;
}
</style>
</head>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>
</body>
我们发现,container这个box容器的高度为0,这就是没有清除item的浮动,(浮动元素会脱离文档流,导致没有撑开父盒子)。
我们传统解决浮动的方法就是:内墙法。在浮动元素的后面加一个空的 块级元素 (通常是div),并且该元素设置 clear:both; 属性。clear属性,字面意思就是清除,那么both,就是清除浮动元素对我左右两边的影响。
<style>
* {
padding: 0;
margin: 0;
}
.container {
background-color: orange;
}
.clearfix {
clear: both;
}
.item {
float: left;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
width: 10%;
height: 100px;
border: 1px solid red;
}
.item:nth-child(odd) {
background-color: #ccc;
}
</style>
</head>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="clearfix"></div>
</div>
</body>
但是我们也可以使用BFC的方法进行清除浮动。
<style>
* {
padding: 0;
margin: 0;
}
.container {
background-color: orange;
overflow: hidden;
}
.item {
float: left;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
width: 10%;
height: 100px;
border: 1px solid red;
}
.item:nth-child(odd) {
background-color: #ccc;
}
</style>
</head>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>
</body>
我们发现这也成功清除了浮动。
但是,这是有一个条件的:那就是父元素的高度为aoto
BFC清除浮动的原理:
BFC的高度是auto的情况下,是如下方法计算高度的:
- 如果只有inline-level,是行高的顶部和底部的距离;
- 如果有block-level,是由最底层的块上边缘和最底层块盒子的下边缘之间的距离;
- 如果有绝对定位元素,将被忽略;
- 如果有浮动元素,那么会增加高度以包括这些浮动元素的下边缘。