BFC 初体验

1 引言

BFC(Block Formatting Context),中文翻译为“块格式化上下文”。它有一个明显的特性,那就是若是一个元素拥有了 BFC 特性,那么它内部元素不受外部元素的影响,外部元素也不会受其内部元素的影响。css

但到底什么才是 BFC 呢?html

先来看看 MDN 对 BFC 的解释。浏览器

2 MDN 对 BFC 的解释

块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,是布局过程当中生成块级盒子的区域,也是浮动元素与其余元素的交互限定区域。ide

下列方式会建立块格式化上下文:wordpress

  • 根元素或包含根元素的元素
  • 浮动元素(元素的 float 不是 none)
  • 绝对定位元素(元素的 position 为 absolute 或 fixed)
  • 行内块元素(元素的 display 为 inline-block)
  • 表格单元格(元素的 display为 table-cell,HTML表格单元格默认为该值)
  • 表格标题(元素的 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)
  • overflow 值不为 visible 的块元素
  • 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,即便该元素没有包裹在一个多列容器中(标准变动,Chrome bug)。

建立了块格式化上下文的元素中的全部内容都会被包含到该BFC中。布局

块格式化上下文对浮动定位(参见 float)与清除浮动(参见 clear)都很重要。浮动定位和清除浮动时只会应用于同一个BFC内的元素。浮动不会影响其它BFC中元素的布局,而清除浮动只能清除同一BFC中在它前面的元素的浮动。外边距折叠(Margin collapsing)也只会发生在属于同一BFC的块级元素之间。flex

感受怎么样?反正我读下来的感受就是:ui

好像也没具体的说什么是 BFC 。spa

3 BFC 的我的理解

我的感受 BFC 就像女孩子的好感同样,无法说清楚什么才算是女孩子对你有好感,可是一旦女孩子对你有好感,你就知道了。翻译

BFC 同理,无法说清楚什么是 BFC ,可是当 BFC 一出现,你就知道那个东西属不属于 BFC ,也就是拥有某些特定属性的东西就是 BFC ,能触发 BFC 的属性 MDN 上都有说明。

4 BFC 的用处

4.1 管住子元素

BFC 元素里面元素不能影响外面的元素,利用这个特性,能够用来管住子元素。

4.1.1 浮动元素

咱们知道,当一个元素变成浮动元素后,那么它就会脱离文档流,对页面布局产生影响,利用 BFC 就可紧紧管住浮动元素,消除这种影响,

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>BFC</title>
</head>

<body>
  <div class="father">
    <div class="child"></div>
  </div>
</body>
<style> .father { width: 300px; border: 1px solid red; } .child { width: 200px; height: 100px; background: pink; } </style>

</html>
复制代码

从动态图中能够看到,当咱们给child元素加一个浮动时,它就会脱离father元素的掌控,若是这时候把father元素变成 BFC (float: left;display: inline-block; 均可以将元素变成 BFC 元素,其余更多方法看 MDN 的解释),那么child元素就会从新被father元素所掌控。

对于清楚浮动,也能够利用clearfix来实现,这个更推荐clearfix,由于 BFC 有反作用,除了display: flow-root以外,其余将元素变成 BFC 的都是给元素加了一个其余的属性,这就会形成反作用。

display: flow-root是一个专门生成 BFC 的一个属性,可是它是一个高级属性,浏览器支持不全面。

4.1.2 margin

当咱们给子元素一个margin时,它的margin部分会跑到父级元素外面去。

当给子元素加一个margin-top: 100px;后,会发现子元素比父元素大了,这个时候把父级元素变成 BFC 后,父级元素又会从新把子元素包进来。

4.2 和兄弟划清界限

BFC 元素外面的元素不能影响其里面的元素,利用这个特性能够和兄弟元素划清界限,不受兄弟元素的影响。

4.2.1 清除外边距叠加

咱们知道,在CSS当中,相邻的两个盒子(多是兄弟关系也多是祖先关系)的外边距能够结合成一个单独的外边距。这种合并外边距的方式被称为折叠,而且于是所结合成的外边距称为折叠外边距。

而当其中一个元素变成了 BFC 以后,里面的子元素就不会与这个元素的相邻元素发生外边距叠加。

来看例子。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>BFC</title>
</head>
<body>
  <div class="child"></div>
  <div class="father">
    <div class="child"></div>
  </div>
  <div class="child"></div>
</body>
<style> .father{ } .child{ width: 200px; height: 100px; background: pink; margin: 20px; } </style>
</html>
复制代码

这时候会发生外边距叠加,它们中间的边距为20px。若是存在 BFC ,就会与旁边的元素划清界限,也就不会发生外边距叠加了。

从代码及动态图能够看到,实际上是father元素里面的child元素与father元素的兄弟元素发生了外边距叠加,当father元素变成 BFC 后,里面的child元素与father元素的兄弟消除了外边距叠加。

咱们来看另一种状况,看下面的动态图。

从图中能够看到,BFC 元素自己不会与其兄弟元素消除外边距叠加,它只能消除其子元素与 BFC 兄弟元素之间的外边距叠加。

4.2.2 打破兄弟浮动元素的压迫

咱们知道当兄弟元素变成浮动元素后,它就会“骑”在咱们身上,这咱们确定不能忍啊。那咋办呢?把咱们本身变成 BFC 就行了。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>BFC</title>
</head>
<body>
<div class="father">
  <div class="child1"></div>
  <div class="child2"></div>
</div>
</body>
<style> .father{ width: 350px; background: #999; } .child1{ float: left; width: 100px; height: 200px; background: pink; } .child2{ display: flow-root; width: 200px; height: 300px; background: red; } </style>
</html>
复制代码

那我想离这个想压迫个人兄弟远点那怎么办?咱们天然而然地想到了margin-left,来试试margin-left: 20px;,来看看效果。

咦?咋没用呢?来看看它的margin

原来兄弟元素虽然不能压迫咱们自身,但它仍旧能够“骑”在咱们的外边距上。正所谓 BFC 的一个特性:外部元素不能影响 BFC 内部元素,但没说外部元素不能影响 BFC 元素自己。

既然这样,那就加大力度,我来个margin-left: 120px

这下却是与兄弟元素分开了,但有一个很大的缺点,当兄弟元素的宽度发生变化时,它们之间的间距也发生了变化,若是想要其间距固定怎么办?

咱们换个思路,把margin写在浮动元素上怎样?

从动态图中能够看到,当margin写在浮动元素上后,无论其宽度怎么变,与兄弟 BFC 元素总会有着固定的间隔。

利用这个特性,咱们能完成一个多栏的布局。

文章中若有错误之处,忘不吝赐教。

参考资料:

相关文章
相关标签/搜索