BFC 是什么?

本文写于 2020 年 7 月 17 日

总有同学问我:“这个 div 为什么会插出来?为什么 float 的 div 这么不好操作?”。这其实就是没有深入理解 BFC 而造成的后果。

BFC,全名 Block Formatting Context,译为块格式化上下文

当我第一次看到这个中文的时候,我觉得这简直就是直译啊!太赤裸裸了!并且翻译过来的这个词语反而让我看不懂了——到底是“块/格式化/上下文”还是“块格式化/上下文”?

看看英语才能明白,是“块/格式化/上下文”。接下来我们要来寻找答案了,BFC 是什么?

第一次接触到这个问题,首选自然是 MDN(求求你们了不要在 CSDN 上看了):

BFC 是 Web 页面的可视 CSS 渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。 —— MDN

我们来分析几个问题。

首先,「块格式化上下文」究竟是一个过程还是一个结果?BFC 是指我去「块格式化」「上下文」,还是指的是,「被块格式化」的「上下文」?

关于这一点,上面写的 MDN 的说法就可以给我们解答,「块格式化上下文」(以下皆用 BFC 来代替称呼)是一个被创建出来的区域

其次,我们做网页为什么需要 BFC 呢?一个概念,如果脱离了实际运用,那我们学来干啥?仅仅为了面试吗?看看 MDN 的解答:

块格式化上下文对浮动定位与清除浮动都很重要。

浮动定位和清除浮动时只会应用于同一个 BFC 内的元素。

浮动不会影响其它 BFC 中元素的布局,而清除浮动只能清除同一 BFC 中在它前面的元素的浮动。

外边距折叠(Margin collapsing)也只会发生在属于同一 BFC 的块级元素之间。

—— MDN

好长一串!不需要全看,第一句话其实就已经点明了 BFC 的具体用途,清除浮动带来的各种奇怪副作用。

CSS 是一个难以捉摸的语言。对于新人来说,CSS 就像是大海一样:用的顺手的时候风平浪静、万里无云;用的不顺的时候乌云滚滚、巨浪滔天。很多人刚学前端就被 CSS 拍碎了船,尸沉大海。

浮动就是一个学习早期就会碰到的副作用。

例如我们用一个 div 包裹着三个 div,并且希望他们可以横向排列。

假设规定必须使用 float: left; 进行操作,那么我们就会发现一个神奇的现象:外层的 div 只有宽,没有高,并且无法设置 margin。

这就是浮动的副作用

1 常见的布局方案

Box 是 CSS 的布局基本单位,即一个网页应该是由很多很多的 Box 构成的。

而 Box 的各种 CSS 属性,决定了 Box 的类型。不同的 Box 会以不同的方式进行渲染。如何处理这些渲染方式,就是我们的布局重点了。

通常我们会使用三种布局方式。

1.1 文档流(普通流 normal flow)

在普通流中,元素按照其在 HTML 中的先后位置至上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行,块级元素则会被渲染为完整的一个新行,除非另外指定,否则所有元素默认都是普通流定位,也可以说,普通流中元素的位置由该元素在 HTML 文档中的位置决定。

1.2 浮动(float)

在浮动布局中,元素首先按照普通流的位置出现,然后根据浮动的方向尽可能的向左边或右边偏移,其效果与印刷排版中的文本环绕相似。

1.3 绝对定位(absolute positioning)

在绝对定位布局中,元素会整体脱离普通流,因此绝对定位元素不会对其兄弟元素造成影响,而元素具体的位置由绝对定位的坐标决定。

以前我们会非常多的用到浮动和绝对定位进行布局,但是人们渐渐的发现这两种方案实在是太多太多副作用了,让开发者苦不堪言。

所以现在流行的 Flex 布局、Grid 布局,都是普通流的布局。再在此基础之上使用绝对定位,事倍功半。

2 BFC

简单来看 BFC 的布局规则是:

  1. 内部的 Box 会在垂直方向依次排序;
  2. Box 的垂直方向距离由 Margin 决定,如果两个相邻的 Box 属于同一个 BFC,那么相邻的 margin 会重叠
  3. 计算高度时,浮动元素也会参与计算;
  4. BFC 是独立的容器,内部不会影响外部,反之亦然。

总结一下,BFC 是页面中的一块渲染区域,并且有一套自己的渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。

可以理解为 BFC 就是一个封闭的大盒子,箱子内部的元素无论如何倒腾,都不会影响到外部的其他的箱子。

那么如何创建一个 BFC 呢?或者说 BFC 的创建规则是什么呢?

MDN 文档为我们列出了如下几种解决方案:

  • 根元素()
  • 浮动元素(元素的 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 或 paint 的元素
  • 弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)
  • 网格元素(display 为 grid 或 inline-grid 元素的直接子元素)
  • 多列容器(元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1)
  • column-span 为 all 的元素始终会创建一个新的 BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。

也有网友也整理的简化版本:

  • body 根元素
  • 浮动元素:float 除 none 以外的值
  • 绝对定位元素:position (absolute、fixed)
  • display 为 inline-block、table-cells、flex
  • overflow 除了 visible 以外的值 (hidden、auto、scroll)

所以归根结底,BFC 有什么用?

1. 阻止元素被浮动元素覆盖

经常当我们 float: left; 之后,正常流的 div 就会被浮动的 div 所遮挡。如果通过设置 div 的 CSS 触发 BFC,就可以阻止浮动的盒子遮挡正常流。

2. 可以包含浮动元素

一般情况下,用一个 div 包裹另一个浮动的 div 时,外层的 div 是无法被撑开的。但通过各种方式让外层成为 BFC,就可以消除浮动带来的副作用。

3. 消除 margin 坍塌(margin-collapse)

当我们发现相邻的两个元素 margin 重叠,说明他们可能是隶属于同一个 BFC 的子元素,我们只需要将他们都变成 BFC,即可消除 margin 的坍塌现象。

(完)

BFC 是什么?的更多相关文章

  1. 深入理解BFC

    定义 在解释BFC之前,先说一下文档流.我们常说的文档流其实分为定位流.浮动流和普通流三种.而普通流其实就是指BFC中的FC.FC是formatting context的首字母缩写,直译过来是格式化上 ...

  2. “fixed+relative==absolute”——对BFC的再次思考

    好久没写博客了,刚好今天跨年夜没约到什么妹子,在家宅着不如写点东西好了. 需求 昨天晚上,给公司年会做一个移动端的投票页面,遇到一个UI优化的问题: · 正文内容少于一屏时,投票提交按钮固定显示在页面 ...

  3. 关于CSS inline-block、BFC以及外边距合并的几个小问题

    CSS inline-block和BCF对于初学者来说,总是弄不太明白,下面记录下我在学习这块知识的过程中遇到的几个问题,供大家参考,有不足的地方,欢迎大家批评指正. 一.在什么场景下会出现外边距合并 ...

  4. 我对BFC的理解

    最初这篇文章打算回答寒冬大神的第一问,谈谈CSS布局.本来呢我以为布局主要涉及float跟display相关属性,以及他们的包含框.静态位置等等.后来看了大神的一片面试文章,嗯?这里怎么还有个BFC, ...

  5. CSS3与页面布局学习总结(三)——BFC、定位、浮动、7种垂直居中方法

    一.BFC与IFC 1.1.BFC与IFC概要 BFC(Block Formatting Context)即“块级格式化上下文”, IFC(Inline Formatting Context)即行内格 ...

  6. 前端精选文摘:BFC 神奇背后的原理

    BFC 已经是一个耳听熟闻的词语了,网上有许多关于 BFC 的文章,介绍了如何触发 BFC 以及 BFC 的一些用处(如清浮动,防止 margin 重叠等).虽然我知道如何利用 BFC 解决这些问题, ...

  7. BFC的形成条件和特性分析

    初学CSS时,我们学到很多有意思的CSS规则,比如外边距塌陷,还有浮动元素的一些特性等,其实这些规则背后都是BFC这个东西在控制,下面我们来看下BFC到底是什么. 什么是BFC BFC(Block f ...

  8. BFC布局

    这几天都没有写博客,自己的懒惰又要跑出来了,发觉不能再这样下去了,不然就什么都不想干了,然后将之前已经写得差不多的博客重新检视了一遍.这篇博客已经写得挺久的了,但是一直没有发布,现在补充了一些,也让自 ...

  9. 浅析CSS中的BFC和IFC

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

  10. BFC深入理解

    BFC 在上一篇文章中,清除浮动方法解析,我们谈及了一些使用css属性解决浮动带来的影响.但是在解决浮动带来的影响的方法中,如果细心思考,会产生如下疑问: 为什么overflow可以清除浮动带来的影响 ...

随机推荐

  1. 爬虫-数据解析-bs4

    1.数据解析 解析: 根据指定的规则对数据进行提取 作用: 实现聚焦爬虫 数据解析方式: - 正则表达式 - bs4 - xpath 数据解析的通用原理: 数据解析需要作用在页面源码中(一组html标 ...

  2. 攻防世界NewsCenter

    NewsCenter 打开题目是一个搜索框我们首先尝试一下sql注入 判断了一下是使用''进行包裹的字符型sql注入 然后我们需要判断数据库列数 1' order by 3# 回显正常但by4的时候回 ...

  3. Rust 中的数据布局--非正常大小的类型

    非正常大小的类型 大多数的时候,我们期望类型在编译时能够有一个静态已知的非零大小,但这并不总是 Rust 的常态. Dynamically Sized Types (DSTs) Rust 支持动态大小 ...

  4. (stm32f103学习总结)—独立看门狗(IWDG)

    一.IWDG介绍 1.1 IWDG简介 STM32F1芯片内部含有两个看门狗外设,一个是独立看门狗IWDG,另 一个是窗口看门狗WWDG.两个看门狗外设(独立和窗口)均可用于检测 并解决由软件错误导致 ...

  5. Linux基础学习 | 目录及文件

    一.目录结构 Linux目录采用树形结构,以根目录/向下延伸呈一个倒置的树的形状. 每个目录下都有其相对应的子目录,而子目录中又有其子目录的存在,就像一棵树的树枝分叉,所有的目录层次结构分明,每个目录 ...

  6. jquery+html5实现单张图片上传预览

    js: if (window.File && window.FileReader && window.FileList && window.Blob){ ...

  7. Angular2入门系列(五)———— 路由参数设置

    Angular2入门系列(五)---- 路由参数设置路由配置: { path: '', component: CarProFile, children: [ { path: 'add', compon ...

  8. 【Android开发】APP桌面角标问题

    Demo:https://github.com/baitutang1221/BadgeNumberManager 参考:https://juejin.im/post/59f2e59751882578c ...

  9. 记住用户名和登录密码+虚拟机没有root权限解决办法

    今日所学: 记住用户名和登录密码 用adb查看保存文件内容 如何使用adb 如何安装adb-百度经验 遇到的问题: 用adb查看文件时,没有权限访问data文件 出现原因:google play虚拟机 ...

  10. linux添加磁盘及分区挂载

    磁盘管理 1.为什么要添加磁盘 随着系统的使用,磁盘的内容会越来越少,所以这时要添加磁盘增加空间 Linux系统中磁盘管理就是将硬盘通过挂载的方式挂载到linux文件系统中. 2.系统添加磁盘并分区 ...