写在最前:BFC看起来是个很陌生的概念但它却时时发生在我们工作中,如何清除浮动影响?如何避免margin穿透问题?如何编写两栏自适应布局?都和BFC有这密不可分的关系,下面走进切图妞的世界,分分钟搞定BFC!
一、什么是BFC?
BFC概念
块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。简而言之,BFC就是一种边距重叠的解决方案。
BFC原理
- BFC内部元素的元素在垂直方向上的边距会发生重叠
- BFC不会与浮动元素重叠
- BFC是独立的容器,不会影响里面的元素,里面的元素也不会影响外面元素
- 计算BFC元素高度时,浮动元素也会参与计算
二、BFC产生条件
主流:
- 根元素或包含根元素的元素
- 浮动元素:float不为none(
float+float具有包裹性和破坏性导致无法自适应,一般用在块状浮动布局
) - 绝对定位元素:position不为static或者relative(
absolute脱离文档流
) - overflow 值不为 visible 的块元素(
overflow可自适应,但由于溢出不可见限制了应用场景
) - 行内块元素:display为inline-block(
inline-block具有包裹性,无法自适应,IE8以下无法识别该属性
) - 表格单元格:元素的 display为 table-cell(HTML表格单元格默认为该值,
table-cell具有包裹性,无溢出特性,绝对宽度也能自适应
)
非主流:
- 表格标题:元素的 display 为 table-caption,HTML表格标题默认为该值
- 匿名表格单元格元素:元素的 display为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table
- display 值为 flow-root 的元素
- contain 值为 layout、content或 strict 的元素
- 弹性元素:display为 flex 或 inline-flex元素的直接子元素
- 网格元素:display为 grid 或 inline-grid 元素的直接子元素
- 多列容器:元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1
- column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中
三、BFC使用场景
1、margin穿透问题1
写样式的时候常常怀疑我的margin是被浏览器吞掉了吗?
作为一个子元素想离父元素上边距有50px的距离,正常情况下是这么显示的
<section class="sec" style="overflow:hidden">
<article class="child">height: 50px;margin-top: 50px;</article>
</section>
.sec { background: #ebf6fd; }
.child { height: 50px;background: #09d;margin-top: 50px; line-height: 50px;}
子元素的margin-top值因为穿透问题没有实现预想效果
解决方法:使父元素变为BFC,添加overflow:hidden的样式,就会实现如下效果
<section class="sec" style="overflow:hidden">
<article class="child">height: 50px;margin-top: 50px;</article>
</section>
2、margin穿透问题2
书写列表结构的时候,margin-top为20px,margin-bottom为20px,预想中应该出现40px的效果,但是正常情况下是这样的:
<section class="margin">
<p>切图妞切图妞切图妞切图妞切图妞切图妞切图妞</p>
<p>切图妞切图妞切图妞切图妞切图妞切图妞切图妞</p>
</section>
.margin {background: #ebf6fd;}
.margin p { margin: 20px auto;background: #09d; line-height: 40px;}
margin-top和margin-bottom在垂直方向的边距会发生重叠现象,margin-top和margin-bottom哪个大就间隔哪个的距离。
解决方法:给子元素再创建一个父元素,使父元素是BFC
<section class="margin">
<div style="overflow:hidden">
<p>切图妞切图妞切图妞切图妞切图妞切图妞切图妞</p>
</div>
<div style="overflow:hidden">
<p>切图妞切图妞切图妞切图妞切图妞切图妞切图妞</p>
</div>
</section>
3、两栏自适应布局
图片与文字组合的结构,我们经常会使图片浮动起来,利用float的包裹性,让文字环绕图片,如下:
<section class="layout">
<img src="img/bqb1.jpg" class="left" alt="" />
<div class="right">
傻人有傻福
</div>
</section>
.layout {background: #ebf6fd;margin-top: 20px;}
.layout .left { float: left; width: 150px;height: 168px;}
.layout .right {background: #09d;text-align: left; }
但是当我们想把图片和文字的区块独立分来一左一右的时候呢?
解决方法:使右侧元素为BFC,添加overflow:hidden的样式
img src="img/bqb1.jpg" class="left" alt="" />
<div class="right" style="overflow:hidden">
傻人有傻福
</div>
</section>
当我们需要图片与文字间距20px时,有两种方法:左侧margin-right或者右侧padding-left
<img src="img/bqb1.jpg" class="left" style="margin-right:20px" />
<div class="right" style="overflow:hidden;padding-left:20px">
傻人有傻福
</div>
4、清除浮动
父元素包含浮动元素,导致父元素塌陷,正常情况如下:
<section class="floatBorder">
<div class="float">切图妞切图妞切图妞切图妞切图妞切图妞切图妞</div>
</section>
.floatBorder { background: #ebf6fd;border: 1px solid #FFBE00;margin-top: 20px;}
.floatBorder .float { float: left; line-height: 50px; background: #08d;}
父元素塌陷除了border外失去高度,此时需要利用BFC内子元素即使是浮动元素也会参与计算的原理
解决方法:使父元素变成BFC,添加清除浮动类
.clearfix {*zoom: 1 }
.clearfix:after {content: '';display: table; clear: both }
四、结语
具有BFC属性的元素是一个独立的容器,它不受子元素影响也不影响子元素!当margin遇到BFC,边距重叠问题得以解决;当BFC元素身边存在浮动时,它拒绝了float的包裹性独立成一个容器不与其重叠;当浮动元素在BFC元素里面时,计算高度时将内部浮动元素也进行计算,解决了父元素塌陷的问题!
上面示例代码已上传,可下载练习修改→BFC Demo
尊重原创,如需转载请注明出处!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。