我们常说的文档流其实分为定位流、浮动流和普通流三种。而普通流其实就是指BFC中的FC。FC是formatting context的首字母缩写,直译过来是格式化上下文,它是页面中的一块渲染区域,有一套渲染规则,决定了其子元素如何布局,以及和其他元素之间的关系和作用。常见的FC有BFC、IFC,还有GFC和FFC。BFC是block formatting context,也就是块级格式化上下文,是用于布局块级盒子的一块渲染区域。

简单来说,BFC 实际上是一块区域,在这块区域中遵循一定的规则,有一套独特的渲染规则。

我们经常说的父级元素触发了 BFC,实际上就是这个元素所在的区域要遵循 BFC 的渲染规则。

那么 BFC 的渲染规则到底是什么呢?

BFC 的原理是什么(BFC 的渲染规则)

1)BFC 区域内的元素外边距会发生重叠

这一点和外部的元素是一样的,如果 BFC 内的相邻元素或父子元素满足边距重叠的条件也会发生重叠

2)BFC 区域内的元素不会与浮动元素重叠

BFC 内的元素不会与外部的浮动元素重叠

3)计算 BFC 区域的高度时,浮动元素也参与计算

清除浮动的原理,浮动元素也能撑开盒子,这也是为什么说父元素触发 BFC 后就可以解决父元素高度塌陷的原因。

4)BFC 区域就相当于一个容器,内部的元素不会影响到外部,同样外部的元素也不会影响到内部。

解决父子元素的外边距重叠问题。

5)BFC 区域内部元素的排列和外部元素是一致的,也遵循块元素占一行,行内块元素不占一行等规则。

如何创建 BFC

平常说的触发 BFC 是针对元素说的,元素触发 BFC 后它所在的区域就变成了一个 BFC 区域,创建 BFC 是针对 BFC 本身来说的,因为它本身就是一个区域,所以用创建。

float 不为 none,浮动元素所在的区域就是一个 BFC 区域。

position 的值不是 static 或 relative 的元素所在的区域就是一个 BFC 区域

displaytable-cell 的表格单元格元素所在的区域也是一个 BFC 区域

overflow 不为 visible 的元素所在的区域也是一个 BFC 区域

下面是 MDN 列举出来的,创建 BFC 的方式

  • 根元素(html) (html 元素所在的区域就是一个 BFC 区域,所以我们平时编写的元素都是在一个 BFC 区域内渲染的,有很多东西为什么要这样应该有些也理解了)
  • 浮动元素(元素的 float 不是 none
  • 绝对定位元素(元素的 positionabsolutefixed
  • 行内块元素(元素的 displayinline-block
  • 表格单元格(元素的 displaytable-cell,HTML表格单元格默认为该值)
  • 表格标题(元素的 displaytable-caption,HTML表格标题默认为该值)
  • 匿名表格单元格元素(元素的 displaytable、``table-rowtable-row-group、``table-header-group、``table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table
  • overflow 值不为 visible 的块元素
  • display 值为 flow-root 的元素
  • contain 值为 layoutcontent或 paint 的元素
  • 弹性元素(displayflexinline-flex元素的直接子元素)
  • 网格元素(displaygridinline-grid 元素的直接子元素)
  • 多列容器(元素的 column-countcolumn-width 不为 auto,包括 ``column-count1
  • column-spanall 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更Chrome bug)。

BFC 规则验证及应用

接下来根据上面列出的几条规则,通过举例一一验证并且说明每条规则到底有什么实际应用。

规则一 BFC 区域内的元素外边距会发生重叠

BFC 区域内的元素和外部元素一样如果满足边距重叠的条件也会发生边距重叠。不知道你有没有发现在 MDN 列举出来的创建 BFC 的方法中,第一条就说 HTML 元素就是一个 BFC,所以我们在页面上写的元素实际上都是在 BFC 区域中。外部元素(其实也是在 BFC 区域内)会发生的事情,BFC 区域内的元素当然也会发生同样的事情。

例如,下面的代码中,两个 article 元素上边距都为 10 px,下边距都为 40 px,但是显示在页面上时发现两个元素的边距只有 40px,发生了边距重叠,并且边距值变成了较大的 40 px。

即使父元素 sec 触发了 BFC,其内部的元素依然会发生边距重叠,这也验证了上面的 BFC 渲染规则中的第一条:BFC 区域内部的元素会发生边距重叠。

  <section id = 'sec'>
<style media="screen">
#sec {
background: yellowgreen;
overflow: hidden;
}
.art1 {
height: 100px;
margin: 10px auto 40px;
background: pink;
}
.art2 {
height: 100px;
margin: 10px auto 40px;;
background: rgb(202, 24, 178);
}
</style>
<article class='art1'>
</article>
<article class='art2'>
</article>
</section>

其实消除边距重叠很简单,只需要给 article2 一个父元素,然后触发 BFC 即可。

  <section id = 'sec'>
<style media="screen">
#sec {
background: yellowgreen;
overflow: hidden;
}
.wrapper {
overflow: hidden;
}
.art1 {
height: 100px;
margin: 10px auto 40px;
background: pink;
}
.art2 {
height: 100px;
margin: 10px auto 40px;;
background: rgb(202, 24, 178);
}
</style>
<article class='art1'>
</article>
<div class='wrapper'>
<article class='art2'>
</article>
</div>
</section>

规则二 BFC 区域的元素不会与外部的浮动元素重叠

如下面的代码中,.art1 和 .art2 元素是相邻的两个元素。

.art1 是粉红色向左浮动元素,.art2 元素会出现在浮动元素的下方和浮动元素重叠。

  <section id = 'sec'>
<style media="screen">
#sec {
background: yellowgreen;
overflow: hidden;
}
.wrapper {
/* overflow: hidden; */
}
.art1 {
float: left;
height: 100px;
width: 100px;
background: pink;
}
.art2 {
height: 200px;
background: rgb(202, 24, 178);
}
</style>
<article class='art1'>
</article>
<div class='wrapper'>
<article class='art2'>
</article>
</div>
</section>

现在我们让 .art2 元素触发 BFC,即给 .wrapper 元素加上 overflow: hidden.结果如下图所示:

可以看到当将 art2 元素触发 BFC 之后,它和浮动元素就不会重叠了。

规则三 计算 BFC 区域的高度时,浮动元素也参与计算(应用:清除浮动)

浮动带来的问题主要就是父元素中的浮动元素不参与高度计算,所以导致父元素高度塌陷,这条规则使得浮动元素也参与到父元素的高度计算,因此这条规则也是清除浮动的原理。

现在令 .art1 元素左浮动。根据下图可以看到,父元素 section 的高度为 0,这说明浮动元素并未参与高度计算。

  <section id = 'sec'>
<style media="screen">
#sec {
background: yellowgreen;
}
.art1 {
float: left;
}
</style>
<article class='art1'>
我是浮动元素
</article>
</section

现在令父元素 section 触发 BFC(例如可以给父元素加一个 overflow: hidden 触发 BFC),结果如下图。

现在可以看到父元素有了高度。

规则四 BFC 区域就相当于一个容器,内部的元素不会影响到外部,同样外部的元素也不会影响到内部(应用:消除边距重叠)

.blue 元素的 margin-bottom 是 12px, .red-inner 元素的 margin-top 也为 10px。这个时候 ,如下图所示,.blue 元素和 .red-outer 元素之间的 margin 为 12px,.red-inner 元素的 margin-top 并没有起作用,发生了外边距塌陷。

  <section id = 'sec'>
<style>
.blue {
height: 50px;
margin-bottom: 12px;
background: blue;
} .red-outer {
background: red;
} .red-inner {
height: 50px;
margin-top: 10px;
}
</style>
<div class="blue">blue</div>
<div class="red-outer">
<div class="red-inner">red inner</div>
</div>
</section>

现在我们令 .red-outer 元素触发 BFC(例如可以给父元素加一个 overflow: hidden 触发 BFC),结果如下图所示。

当触发 BFC 之后,.red-outer 元素就是一块 BFC 区域了,利用规则四,内部的元素和外部的元素相互不影响,.red-inner 元素是内部的元素,因此它不会再和父元素 .red-outer 的外边距重合了(可以这样理解 父元素的 margin 就是外部区域了)。所以现在它的 margin-top 10px 是相对于父元素的,由于父元素的宽度是由它撑开的,因此现在父元素的高度变成了 60px。

规则五 BFC 区域内部元素的排列和外部元素是一致的,也遵循块元素占一行,行内块元素不占一行等规则。

这个前面已经提到过了,在 MDN 触发 BFC 的第一条就是 HTML 元素,可见 HTML 元素所在的区域就是一个 BFC 区域。因此 BFC 区域的内部元素和外部元素的行为是一致的,也遵循块级元素独占一行,行内块元素不占一行等规则。

完,如果发现有什么问题麻烦指正,非常感谢。

CSS 中你应该了解的 BFC的更多相关文章

  1. 浅析 CSS 中的边距重叠

    浅析 CSS 中的边距重叠 边距重叠是什么 在说边距重叠之前,先以正常的思维来考虑如果你现在是浏览器引擎遇到这种情况应该怎么办? 现在有两个元素 div1 和 div2 紧挨着,中间没有它元素,它们的 ...

  2. 浅析CSS中的BFC和IFC

    1. 为什么会有BFC和IFC 首先要先了解两个概念:Box和formatting context: Box:CSS渲染的时候是以Box作为渲染的基本单位.Box的类型由元素的类型和display属性 ...

  3. BFC?来自CSS中的BFC

    浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子 ...

  4. 理解CSS中BFC

    BFC(Block Formatting Context) 是Web页面中盒模型布局的CSS渲染模式.它的定位体系 属于 常规文档流 .摘自 W3C : 浮动,绝对定位元素, inline-block ...

  5. CSS中的IFC和BFC入门

    CSS中的IFC和BFC入门   提到CSS,首先会想到的就是盒模型,如果对于盒模型不是很理解的,看这里.这是一个基础的系列,看了盒模型还可以看看box-sizing,好了不多说了,下面介绍今天的重点 ...

  6. 是的,是你的BFC - CSS中常用

    是的,是你的BFC - CSS中常用     是的,是你的BFC - CSS中常用 CFC 全称:(Block Formatting Contexts)含义是块级格式化上下文),就是一个块级元素的渲染 ...

  7. CSS中重要的BFC

    CSS中有个重要的概念BFC,搞懂BFC可以让我们理解CSS中某些原本看似诡异的地方. 简介 在解释BFC之前,先说一下文档流.我们常说的文档流其实分为定位流.浮动流.普通流三种.而普通流其实就是指B ...

  8. 总结下对我对于CSS中BFC的认知

    首先第一个,什么是BFC? BFC的全称叫Block  Formatting  Context   (块级格式化上下文)BFC是css中隐含属性,开启BFC后元素会变成一个独立的布局环. 简单来说,它 ...

  9. css中的一些属性解析

    1.inline-block 存在问题:inline-block的相互间距,元素之间会有一个左右2px的margin一样产生            请看中间的空隙. 为什么会产生这个空隙呢?? 怎么解 ...

随机推荐

  1. vue的使用经验

    导读 这一次的口号是,带你重新认识vue,拯救1,2个前端开发者. 从2018年从事前端职业以来,呆过大小公司,干这一行都有2年多.代码写的多了,就越来越体会新手程序员都是挖坑的.在工作过程中,用一种 ...

  2. ubuntu 16.04配置svn服务器

    为了操作方便,使用root登录服务器. 一.安装svn服务器 -->apt-get install subversion 二.创建svn版本库,存放需要管理内容路径 -->mkdir sv ...

  3. Prism 源码解读2-View的加载和控制

    介绍 上一篇介绍了Region,这一篇跟Region息息相关,讲一下Region中View的加载方式及控制. 4.ViewDiscovery 在创建好Region后需要将View添加到Region中. ...

  4. 参加Folding@Home(FAH)项目,为战胜新冠肺炎贡献出自己的一份力量

    鉴于新冠病毒(COVID-19)在全球范围内的大规模传播,PCMR和NVIDIA呼吁全球PC用户加入Folding@home项目贡献自己闲置的GPU计算力,协助抗击新冠状病毒疫情. 目前全球有超过40 ...

  5. 使用TensorFlow v2.0构建多层感知器

    使用TensorFlow v2.0构建一个两层隐藏层完全连接的神经网络(多层感知器). 这个例子使用低级方法来更好地理解构建神经网络和训练过程背后的所有机制. 神经网络概述 MNIST 数据集概述 此 ...

  6. HDU - 1962 二分图最大匹配模板(扑克牌得分最大)

    题意: 直接说数据,第一行给定几组数据,每一组数据的第一行是两个人扑克牌分别的数量,第一行是亚当的扑克牌,第二行是夏娃的扑克牌,每一个扑克牌的大小用两个字符来表示,第一个表示是几号扑克牌,第二个表示扑 ...

  7. adb基本命令操作(四)

    一,基本操作命令 adb shell:进入手机系统 说明:root表示手机当前的操作用户,也是最高权限操作者 cd ,可以切换目录,执行cd /sdcard  表示手机内部的存储路径,也是表示内部存储 ...

  8. 洛谷 P2656 采蘑菇 树形DP+缩点+坑点

    题目链接 https://www.luogu.com.cn/problem/P2656 分析 这其实是个一眼题(bushi 发现如果没有那个恢复系数,缩个点就完了,有恢复系数呢?你发现这个恢复系数其实 ...

  9. 基于vue-cli-和element-ui的开发admin(1)

    //首先以下仅是记录个人本次vue后台管理系统的登录界面部分操作的流程以及踩坑的注意点 一.首先是搭建vue-cli工作环境 这里有两种方式:1.用npm:(在安装了vue,vue-cli以及webp ...

  10. iOS 编译过程原理(2)

    一.前言 <iOS编译过程的原理和应用>文章介绍了 iOS 编译相关基础知识和简单应用,但也很有多问题都没有解释清楚: Clang 和 LLVM 究竟是什么 源文件到机器码的细节 Link ...