深入理解BFC

43次阅读

共计 2729 个字符,预计需要花费 7 分钟才能阅读完成。

一、什么是 BFC
Formatting context 是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。最常见的 Formatting context 有 Block fomatting context (简称 BFC) 和 Inline formatting context (简称 IFC)。Block formatting context 直译为 ” 块级格式化上下文 ”。它是一个独立的渲染区域,只有 Block-level box 参与,它规定了内部的 Block-level Box 如何布局,并且与这个区域外部毫不相干。通俗地讲,BFC 是一个容器,用于管理块级元素。
二、如何创建 BFC

float 为 left|right
overflow 为 hidden|auto|scroll
display 为 table-cell|table-caption|inline-block|inline-flex|flex
position 为 absolute|fixed
根元素

三、BFC 布局规则:

内部的 Box 会在垂直方向,一个接一个地放置 (即块级元素独占一行)。
BFC 的区域不会与 float box 重叠 (利用这点可以实现自适应两栏布局)。
内部的 Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠 (margin 重叠三个条件: 同属于一个 BFC; 相邻; 块级元素)。
计算 BFC 的高度时,浮动元素也参与计算。(清除浮动 haslayout)
BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。

四、BFC 有哪些特性
特性 1:BFC 会阻止垂直外边距折叠
按照 BFC 的定义,只有同属于一个 BFC 时,两个元素才有可能发生垂直 margin 的重叠,这个包括相邻元素或者嵌套元素,只要他们之间没有阻挡(比如边框、非空内容、padding 等)就会发生 margin 重叠。
①相邻兄弟元素 margin 重叠问题
<style>
p{
color: #fff;
background: #888;
width: 200px;
line-height: 100px;
text-align:center;
margin: 100px;
}
</style>
<body>
<p>ABC</p>
<p>abc</p>
</body>
上面例中两个 P 元素之间距离本该为 200px, 然而实际上只有 100px, 发生了 margin 重叠。遇到这种情形,我们如何处理?只需要在 p 外面包裹一层容器,并触发该容器生成一个 BFC。那么两个 P 便不属于同一个 BFC,就不会发生 margin 重叠了。
<style>
p{
color: #fff;
background: #888;
width: 200px;
line-height: 100px;
text-align:center;
margin: 100px;
}
.wrap{
overflow:hidden;
}
</style>
<body>
<p>ABC</p>
<div class=”wrap”>
<p>abc</p>
</div>
</body>

②父子元素 margin 重叠问题
<style>
.box{
width:100px;
height:100px;
background:#ccc;
}
.wrap {
background:yellow;
}
.wrap h1{
background:pink;
margin:40px;
}
</style>
<body>
<div class=”box”>box</div>
<div class=”wrap”>
<h1>h1</h1>
</div>
</body>
上图 wrap 元素与 h1 元素之间 l 理论上本该有个 40px 的上下 margin 值, 然而实际上父子元素并没有存在 margin 值,与此同时,两个 div 元素的间距为 40px。遇到这种情形,我们如何处理?处理方法其实有很多,在 wrap 元素中添加:overflow:hidden; 或者 overflow:auto;使其父元素形成一个 BFC;也可以在 wrap 元素中添加 border:1px solid;或是 padding:1px;这些都可以有效解决父子元素 margin 重叠问题。

特性 2:BFC 不会重叠浮动元素
利用这个特性,我们可以创造自适应两栏布局。
<style>
.box1{
height: 100px;
width: 100px;
float: left;
background: lightblue;
}
.box2{width: 200px;
height: 200px;
background: #eee;
}
</style>
<body>
<div class=”box1″> 我是一个左浮动的元素 </div>
<div class=”box2″> 喂喂喂! 大家不要生气嘛,生气会犯嗔戒的。悟空你也太调皮了,
我跟你说过叫你不要乱扔东西,你怎么又……你看,我还没说完你就把棍子给扔掉了!
月光宝盒是宝物,你把它扔掉会污染环境,要是砸到小朋友怎么办,就算砸不到小朋友,
砸到花花草草也是不对的。</div>
</body>
上图中,文字围绕着浮动元素排列,不过在这里,这显然不是我们想要的。此时我们可以为.box2 元素的样式加上 overflow:hidden;使其建立一个 BFC, 让其内容消除对外界浮动元素的影响。
这个方法可以用来实现两列自适应布局,效果不错,此时左边的宽度固定,右边的内容自适应宽度。如果我们改变文字的大小或者左边浮动元素的大小,两栏布局的结构依然没有改变!
特性 3:BFC 可以包含浮动 —- 清除浮动
我们都知道浮动会脱离文档流,接下来我们看看下面的例子:
<style>
.box1{
width:100px;
height:100px;
float:left;
border: 1px solid #000;
}
.box2{
width:100px;
height:100px;
float:left;
border: 1px solid #000;
}
.box{
background:yellow
}
</style>
<body>
<div class=”box”>
<div class=”box1″></div>
<div class=”box2″></div>
</div>
</body>

由于容器内两个 div 元素浮动,脱离了文档流,父容器内容宽度为零(即发生高度塌陷),未能将子元素包裹住。解决这个问题,只需要把把父元素变成一个 BFC 就行了。常用的办法是给父元素设置 overflow:hidden。
本文于 2018.10.14 重新修改,希望文章对你有些许帮助,欢迎在我的 GitHub 博客点赞和关注,感激不尽!
参考文章
【CSS】深入理解 BFC 原理及应用
10 分钟理解 BFC 原理

正文完
 0