块级格式化上下文 (BFC)
1. 什么是BFC
BFC(Block Formatting Context)是一个独立的渲染区域,在这个区域内的布局不会影响到这个区域之外的元素。换句话说,它就像一个隔离的空间,里面的元素布局与外面的元素布局互不影响。
2. 如何创建BFC
-
浮动元素:当一个元素被设置为
float
(除了none
以外的值)时,它会创建一个新的BFC。 -
绝对定位元素:当一个元素被设置为
position: absolute
或position: fixed
时,它会脱离文档流并创建一个新的BFC。 -
display值为inline-block, table-cell, table-caption, flex, grid的元素:这些元素也会创建新的BFC。
-
overflow属性不为visible的值:当元素的
overflow
属性设置为auto
、scroll
或hidden
时,会创建新的BFC。
3. BFC的特性与用途
-
阻止外边距折叠:两个相邻的块级盒子的外边距会发生折叠,但是它们属于不同的BFC时,外边距不会折叠。
-
包含浮动元素:BFC可以包含浮动元素,防止它们影响周围的布局。
-
防止垂直外边距重叠:属于不同BFC的块级元素之间的垂直外边距不会重叠。
-
可以创建自适应两栏布局:通过创建BFC,可以实现两栏布局,其中一栏的内容可以自适应宽度。
4. 防止垂直外边距重叠
现象
代码如下:
<style>
p {
color: #f55;
background: #fcc;
width: 200px;
line-height: 100px;
text-align: center;
margin: 100px;
}
</style>
<body>
<p>Haha</p>
<p>Hehe</p>
</body>
审查元素,发现应该有2个margin,实际却只有1个margin
解决方法
在第二个p标签外再包一层容器,并形成一个新的BFC,这样两个就不属于同一个BFC,就不会出现问题了
代码如下:
<style>
p {
color: #f55;
background: #fcc;
width: 200px;
line-height: 100px;
text-align: center;
margin: 100px;
}
.wrap {
overflow: hidden;
}
</style>
<body>
<p>Haha</p>
<div class="wrap">
<p>Hehe</p>
</div>
</body>
5. 包含浮动元素
现象
<style>
.par {
border: 5px solid #fcc;
width: 300px;
}
.child {
border: 5px solid #f66;
width: 100px;
height: 100px;
float: left;
}
</style>
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
解决方法
<style>
.par {
border: 5px solid #fcc;
width: 300px;
overflow: hidden;
}
.child {
border: 5px solid #f66;
width: 100px;
height: 100px;
float: left;
}
</style>
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
6. 创建自适应两栏布局
现象
<style>
body {
width: 300px;
position: relative;
}
.aside {
width: 100px;
height: 150px;
float: left;
background: #f66;
}
.main {
height: 200px;
background: #fcc;
}
</style>
<body>
<div class="aside"></div>
<div class="main"></div>
</body>
解决方法
<style>
body {
width: 300px;
position: relative;
}
.aside {
width: 100px;
height: 150px;
float: left;
background: #f66;
}
.main {
height: 200px;
background: #fcc;
overflow: hidden;
}
</style>
<body>
<div class="aside"></div>
<div class="main"></div>
</body>