一、什么是 BFC
BFC
全称 Block Formatting Context
, 中文可译为 块级格式化上下文
- 对于浮动元素、绝对定位元素、非块级盒子的块级容器(
inline-block
、table-cells
、table-captions
)、overflow
值不为 visiable
的块级盒子, 容器内部将创建新的 BFC
- 具备
BFC
特性的元素, 内部将形成独立的渲染区域, 可以看成是一个容器, 容器内的元素和外部元素互不影响
- 在
BFC
内, 块容器从顶端开始垂直地一个接一个地排列, 两个容器之间的垂直的间隙是由他们的 margin
值所决定的, 在同一个 BFC
中, 两个相邻的 块级盒子
的垂直外边距会产生折叠, 注意这里说的是 块级盒子
是指 display
的值为 block
的块级容器, 如果一个容器是 block
一个是 inline-block
那么他们的 margin
是不会发生折叠(下面将会进行详细描述)
二、如何触发 BFC
- 根元素
<html>
自带 BFC
特性
float
属性值不为 none
overflow
属性值不为 visible
(默认值)
display
属性值为 table-cell
table-caption
inline-block
flow-root
中的任何一个
position
属性值不为 relative
和 static
三、BFC 特性(应用场景)
3.1 BFC 内容器排列规律
BFC
里面的容器都会以垂直方向排列, 并且两个相邻 块级容器
的上下 margin
会发生重叠
<style>
.box{
width: 100px;
height: 100px;
margin: 20px;
border: 2px solid red;
}
.parent {
display: flow-root;
}
</style>
<div class="parent">
<div class="box"></div>
<div class="box"></div>
</div>
BFC
内 margin
值合并只针对两个块级容器(display
的值为 block
), 如下例子一个容器是 block
一个是 inline-block
那么他们的 margin
是不会发生合并
<style>
.box{
width: 100px;
height: 100px;
margin: 20px;
border: 2px solid red;
}
.box1 {
display: inline-block;
}
.parent {
display: flow-root;
}
</style>
<div class="parent">
<div class="box box1"></div>
<div class="box"></div>
</div>
- 上面例子中
box1
设置了 display: inline-block
会触发了 box1
容器的 BFC
, 但是 box1
容器是否触发 BFC
并不会影响 margin
的合并, 主要是因为 margin
的合并现象只针对块级容器, 下面例子将 display: inline-block
修改为 overflow: hidden;
同样触发了 box1
容器 BFC
, margin
依然发生重叠
<style>
.box{
width: 100px;
height: 100px;
margin: 20px;
border: 2px solid red;
}
.box1 {
overflow: hidden;
}
.parent {
display: flow-root;
}
</style>
<div class="parent">
<div class="box box1"></div>
<div class="box"></div>
</div>
3.2 BFC 解决 margin 穿透问题
margin
穿透现象: 如下演示代码, 子元素设置了 margin
但是 margin
并没有作用与父元素(和父元素间没有产生间距), 而是作用于父元素相邻的元素上
<style>
.parent {
background: rgba(255, 0, 0, 0.5);
}
.child {
width: 100px;
height: 100px;
margin-top: 50px;
background: rgba(0, 255, 0, 0.5);
}
</style>
<div>这是和父元素相邻的元素</div>
<div class="parent">
<div class="child"></div>
</div>
- 解决办法: 为父元素创建
BFC
, 如此容器内外元素就不会产生干扰
<style>
.parent {
display: flow-root;
background: rgba(255, 0, 0, 0.5);
}
.child {
width: 100px;
height: 100px;
margin-top: 50px;
background: rgba(0, 255, 0, 0.5);
}
</style>
<div>这是和父元素相邻的元素</div>
<div class="parent">
<div class="child"></div>
</div>
3.3 BFC 解决子元素浮动, 容器高度塌陷问题
- 当子元素发生浮动的情况下, 浮动元素不再参与父元素高度的计算
<style>
.parent {
background: rgba(255, 0, 0, 0.5);
}
.child {
float: left;
width: 100px;
height: 100px;
background: rgba(0, 255, 0, 0.5);
}
</style>
<div class="parent">
parent
<div class="child"></div>
</div>
- 解决办法: 触发父容器
BFC
, 浮动元素将会参与父元素高度的计算
<style>
.parent {
display: flow-root;
background: rgba(255, 0, 0, 0.5);
}
.child {
float: left;
width: 100px;
height: 100px;
background: rgba(0, 255, 0, 0.5);
}
</style>
<div class="parent">
parent
<div class="child"></div>
</div>
3.4 解决兄弟容器和浮动元素重叠问题
- 当容器进行浮动时, 该浮动容器将和其兄弟容器进行重叠
<style>
.parent {
background: rgba(255, 0, 0, 0.5);
}
.float {
float: left;
width: 100px;
height: 100px;
background: rgba(0, 255, 0, 0.5);
}
</style>
<div class="parent">
<div class="float"></div>
<div class="content">
在 `BFC` 内, 块容器从顶端开始垂直地一个接一个地排列,
两个容器之间的垂直的间隙是由他们的 `margin` 值所决定的,
在同一个 `BFC` 中, 两个相邻的 `块级盒子` 的垂直外边距会产生折叠,
注意这里说的是 `块级盒子` 是指 `display` 的值为 `block` 的块级容器,
如果一个容器是 `block` 一个是 `inline-block` 那么他们的 `margin`
是不会发生折叠(下面将会进行详细描述)
</div>
</div>
- 解决办法: 只需要触发兄弟容器(非浮动容器)的
BFC
就能够解决重叠问题, 实现自适应双栏布局
<style>
.parent {
background: rgba(255, 0, 0, 0.5);
}
.float {
float: left;
width: 100px;
height: 100px;
background: rgba(0, 255, 0, 0.5);
}
.content {
display: flow-root;
}
</style>
<div class="parent">
<div class="float"></div>
<div class="content">
在 `BFC` 内, 块容器从顶端开始垂直地一个接一个地排列,
两个容器之间的垂直的间隙是由他们的 `margin` 值所决定的,
在同一个 `BFC` 中, 两个相邻的 `块级盒子` 的垂直外边距会产生折叠,
注意这里说的是 `块级盒子` 是指 `display` 的值为 `block` 的块级容器,
如果一个容器是 `block` 一个是 `inline-block` 那么他们的 `margin`
是不会发生折叠(下面将会进行详细描述)
</div>
</div>
- 补充: 上面例子中如何设置两个容器的间距
- 为浮动容器设置
margin-right
- 为非浮动容器设置
padding-left
- 为非浮动容器设置
margin-left
, 主要这里的属性值要大于浮动容器宽度才有效果, 所以这里不推荐该方法
<style>
.parent {
background: rgba(255, 0, 0, 0.5);
}
.float {
float: left;
width: 100px;
height: 100px;
background: rgba(0, 255, 0, 0.5);
/* margin-right: 20px; */
}
.content {
display: flow-root;
/* padding-left: 20px; */
margin-left: 120px;
}
</style>
<div class="parent">
<div class="float"></div>
<div class="content">
在 `BFC` 内, 块容器从顶端开始垂直地一个接一个地排列,
两个容器之间的垂直的间隙是由他们的 `margin` 值所决定的,
在同一个 `BFC` 中, 两个相邻的 `块级盒子` 的垂直外边距会产生折叠,
注意这里说的是 `块级盒子` 是指 `display` 的值为 `block` 的块级容器,
如果一个容器是 `block` 一个是 `inline-block` 那么他们的 `margin`
是不会发生折叠(下面将会进行详细描述)
</div>
</div>
四、参考
- CSS深入理解流体特性和BFC特性下多栏自适应布局
- 快速了解CSS display:flow-root声明
- 块格式化上下文
- 深入理解BFC和Margin Collapse
发表评论
还没有评论,快来抢沙发吧!