【前端帮帮忙】第8期 关于BFC,你需要了解的

栏目: CSS · 发布时间: 5年前

内容简介:BFC是耳熟能详的一个东西了,经常听到,其实在项目中也经常用到,比如最常用的清除浮动,自适应两栏布局等等。只是都没有去深究其原理和相关的知识点,今天就一起来好好学习一下吧。要明白MDN对其描述如下:

BFC是耳熟能详的一个东西了,经常听到,其实在项目中也经常用到,比如最常用的清除浮动,自适应两栏布局等等。只是都没有去深究其原理和相关的知识点,今天就一起来好好学习一下吧。

要明白 BFC 是什么,我们要先来了解几个相关的概念。

盒模型

MDN对其描述如下:

当对一个文档进行布局(lay out)的时候,浏览器的渲染引擎会根据标准之一的 CSS基础盒模型(CSS basic box model) ,将所有元素表示为一个个矩形的盒子(box)。CSS决定这些盒子的大小、位置和以及属性(例如颜色、背景、边框尺寸...)。

每个盒子由四个部分(或称区域)组成,其效用由它们各自的边界(Edge)所定义(原文:defined by their respective edges,可能意指容纳、包含、限制等)。如图,与盒子的四个组成区域相对应,每个盒子有四个边界:内容边界 Content edge、内边距边界 Padding Edge、边框边界 Border Edge、外边框边界 Margin Edge。

【前端帮帮忙】第8期 关于BFC,你需要了解的

我们在浏览器的控制台也可以很清楚的看到页面的每一个元素(除了单独的文本元素),其实都是一个盒子:

【前端帮帮忙】第8期 关于BFC,你需要了解的

更加详细的介绍可以参考MDN或者W3C规范的描述:

www.ayqy.net/doc/css2-1/…

视觉格式化模型

MDN 对其描述如下:

CSS视觉格式化模型(visual formatting model)是用来处理和在视觉媒体上显示文档时使用的计算规则。该模型是CSS的基础概念之一。

视觉格式化模型会根据 CSS盒子模型 将文档中的元素转换为一个个盒子,每个盒子的布局由以下因素决定:

  • 盒子的尺寸:精确指定、由约束条件指定或没有指定
  • 盒子的类型:行内盒子(inline)、行内级盒子(inine level)、原子行内级盒子(atomic inine-level)、块盒子(block)
  • 定位方案(position scheme):普通流定位、浮动定位或绝对定位
  • 文档树中的其他元素:即当前盒子的子元素或兄弟元素
  • 视口尺寸与位置
  • 所包含的图片的尺寸
  • 其他的某些外部因素

关于不同类型盒子的介绍,大家可以直接看MDN,写的很详细了,这里就不再阐述。这边着重讲下 定位方案

定位方案

一旦生成了盒子,CSS引擎就需要定位它们以完成布局。在定位的时候,浏览器会根据元素的盒类型和上下文对这些元素进行定位,可以说盒就是定位的基本单位。定位时有三种定位方案,分别是:常规流(即普通流)、浮动流以及绝对定位。

常规流(Normal flow)

  • 在常规流中,盒子一个接着一个排列;
  • 块级格式化上下文 里面,它们 竖着 排列;
  • 行内格式化上下文 里面,它们 横着 排列;
  • positionstaticrelative ,并且 floatnone 时,会触发常规流
  • 对于 静态定位 (static positioning), position: static ,盒的位置是常规流布局里的位置;
  • 对于 相对定位 *(relative positioning), position: relative ,盒偏移位置右这些属性定义: topbottomleftright即使有偏移,仍然保留原有的位置 ,其他常规流不能占用这个位置。

浮动(Floats)

  • 盒成为浮动盒(floating boxes);
  • 它定位于当前行的开头或末尾;
  • 导致常规流环绕在它的周边 ,除非设置 clear 属性;

绝对定位(Absolute positioning)

  • 绝对定位方案, 盒从常规流中被移除 ,不影响常规流的布局;
  • 它的定位相对于它的包含块,相关CSS属性: topbottomleftright
  • 对于 position: absolute ,元素定位相对于最近的一个 relativeabsolutefixed 的父元素,如果没有则相对于 body

FC(Formatting context)

Formatting context是W3C CSS2.1规范中的一个概念。它是页面中一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。最常见的Formatting context有Block formatting context(简称BFC)和Inline formatting context(简称IFC)。

CSS2.1中只有 BFCIFC ,CSS3中还增加了 GFCFFC 。我们主要来讲下 BFC

好了,接下来轮到我们的主角 BFC 出场了。

BFC是什么

BFC (Block Formatting Context)直译为 块级格式化上下文 。它是一个独立的渲染区域,只有 Box-level box 参与,它规定了内部的Block-level box如何布局,并且与这个区域外部毫不相干。

讲了这么多概念,说下自己的理解,如果有不对的地方,烦请指出,感激不尽。

  • 当我们对一个页面进行布局的时候,浏览器的渲染引擎会根据 CSS的盒模型 将所有元素表示为一个个盒子;
  • 盒子的定义是由 视觉格式化模型 来定义的,盒子的类型可以分为:行内盒子(inline)、行内级盒子(inine level)、原子行内级盒子(atomic inine-level)、块盒子(block);
  • 接下来就是真正的布局开始,浏览器会根据盒子的类型和所处的上下文来对这些元素进行定位,定位有3种方案,分别是:普通流、浮动流和绝对定位。
  • 普通流中的盒子就是属于一个格式化上下文,可能是块或是行内(格式化上下文),但不能两者都是。块级盒参与块格式化上下文。行内级盒参与行内格式化上下文。

是不是可以这样理解: BFC 就是普通流中的元素布局定位时的一个执行环境?

BFC布局规则

  • 内部的Box会在垂直方向,一个接一个的放置。(这边不是很理解,内部的Box不是也可能有行内元素吗?行内元素不是按水平方向来排列吗?这边可能还需要参考行内格式化上下文来理解,还有一个是 writing-mode 属性。)
  • Box垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻Box的 margin 会发生重叠
  • 每个元素的margin box的左边,与包含快border box的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此(除非该盒建立了一个新的块格式化上下文)
  • BFC 的区域不会与float box重叠
  • BFC 就是页面上的一个隔离的独立的容器,容器里面的子元素不会影响到外面的元素,反之亦如此
  • 计算 BFC 的高度时,浮动元素也参与计算

如何创建BFC

  • 根元素
  • float 属性值不为 none
  • positionabsolutefixed
  • displayinline-blocktable-celltable-captionflexinline-flex
  • overflow 不为 visible
  • ...

其实还有很多,这里列出的是一些比较常用的,跟详细的可以看MDN。

通过几个实例来加深理解

1.自适应两栏布局

实现自适应两栏布局的方法有很多,但是我觉得 BFC 的方式应该是最简单的了。

<body>
  <div class="container">
    <div class="side"></div>
    <div class="main"></div>
  </div>
</body>
复制代码
.container {
  width: 400px;    
}

.side {
  float: left;
  width: 100px;
  height: 100px;
  background: lightpink;
}

.main {
  height: 300px;
  background: lightblue;
}
复制代码

页面截图:

【前端帮帮忙】第8期 关于BFC,你需要了解的

根据 BFC 布局规则第3条:

每个元素的margin box的左边,与包含快border box的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此(除非该盒建立了一个新的块格式化上下文)

即使存在浮动元素 sidemain 的左边依然会与包含快的左边相接触。

根据 BFC 布局规则第4条:

BFC 的区域不会与float box重叠

所以,我们可以给 main 创建一个新的 BFC ,这样就不会跟浮动的 side 重叠了,它会根据包含块的宽度和 side 的宽度,自动变窄。

main 加上 overflow: hidden

main {
  overflow: hidden;
}
复制代码

再来看下效果:

【前端帮帮忙】第8期 关于BFC,你需要了解的

2.清除内部浮动

<div class="parent">
  <div class="child"></div>
</div>
复制代码
.parent {
   width: 200px;
   border: 2px solid blue;
   background: lightblue;
}

.child {
  float: left;
  width: 100px;
  height: 100px;
  border: 2px solid red;
  background: lightcoral;
}
复制代码

页面截图:

【前端帮帮忙】第8期 关于BFC,你需要了解的

可以看到,由于子元素设置了浮动,而父元素又没有设置高度,导致父元素高度塌陷了:没有自动被子元素的高度撑开。

根据 BFC 布局规则第6条:

计算BFC的高度时,浮动元素也参与计算

我们可以给父元素 parent 触发 BFC ,那么它在计算高度时,内部的浮动元素也会参与计算。

.parent {
  overflow: hidden;
}
复制代码

再看下效果:

【前端帮帮忙】第8期 关于BFC,你需要了解的

3.阻止margin重叠

<div class="box">box</div>
<div class="box">box</div>
复制代码
.box {
  width: 200px;
  height: 200px;
  margin: 100px;
  background: red;
}
复制代码

页面截图:

【前端帮帮忙】第8期 关于BFC,你需要了解的

根据 BFC 布局规则第2条:

Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠

可以看到,第一个div的下边距跟第二个的上边距发生了重叠。

重叠的结果按照如下规则计算:

  • 两个相邻的外边距都是正数时,重叠结果是它们两者之间较大的值。
  • 两个相邻的外边距都是负数时,重叠结果是两者绝对值的较大值。
  • 两个外边距一正一负时,重叠结果是两者的相加的和。

产生折叠的必备条件:margin必须是邻接的!

我们只要给其中一个div外层再包裹一层div,然后触发其生成一个新的 BFC ,它们就不会发生重叠了。

<div class="box">box</div>
<div class="new-bfc">
  <div class="box">box</div>
</div>
复制代码
.new-bfc {
  overflow: hidden;
}
复制代码

页面截图:

【前端帮帮忙】第8期 关于BFC,你需要了解的

还有很多其他的例子,比如可以避免文字环绕、多列布局等等,这里就不再一一列举,大家有兴趣的可以自己多尝试下,这里有一个网址可以在线演示,更加直观, 链接地址: www.cnblogs.com/xiaohuochai…

创建BFC的新方式

我们上面举的例子都是通过 overflow 来创建 BFC ,但是其实这个方法会有两个问题。

  1. 这些方法本身是有自身的设计目的的,所以在使用它们创建 BFC 时可能会存在一些副作用。例如,使用 overflow 创建 BFC 后,在某些情况下可能会看到出现一个滚动条或者元素内容被裁切。这是由于 overflow 属性的设计是用来让你告诉浏览器如何定义元素的溢出状态的。浏览器执行了它最基本的定义。
  2. 另一个问题是,即使在没有出现副作用的情况下,使用 overflow 也可能会使另一个开发人员感到困惑。他们可能会各种猜想:这里为什么要把 overflow 的值设为 autohidden ?原来的开发人员这样做的意义是什么?原来的开发人员是想让这里出现滚动条吗?

所以实际项目开发中,还需要根据项目的需求来选择合适的方法,最好也能在代码里写明注释。

那有没有什么更好的方式呢?CSS工作组定义了一个新的属性值: display: flow-root

你可以使用 display: flow-root 安全的创建 BFC ,来解决上文中提到的各种问题:自适应两栏布局、清除内部浮动、阻止margin重叠等等。

caniuse上 display: flow-root 在各浏览器的兼容情况,看图:

【前端帮帮忙】第8期 关于BFC,你需要了解的

目前来看,兼容性还是差了一点。

有关于 flow-root 的详细介绍可以看这篇文章: www.w3cplus.com/css3/displa…

BFC概念理解

可以想象一下, BFC 就相当于我们现实中的一个纸箱(盒子),箱子里面的东西的放置(布局)是不会受到外部其他东西的影响的,它形成了一个独立的封闭的区域。当然它里面东西的放置(布局)也不会影响到外面的东西。

最后

感谢您的阅读,希望对你有所帮助,希望你能通过这篇文章能对 BFC 有一个比较全面的理解并能实际应用到项目开发中。本人水平有限,如果文中有不当的地方烦请指正,感激不尽。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

粒子群优化算法及其工程应用

粒子群优化算法及其工程应用

刘波 / 2010-8 / 28.00元

《粒子群优化算法及其工程应用》的主要内容是:粒子群优化(PSO)算法是一种基于群体智能的新兴演化计算技术,广泛用于解决科学研究和工程实践中的优化问题。《粒子群优化算法及其工程应用》主要阐述粒子群优化算法的基本理论及其在机械故障诊断和机械工程测试中的应用成果。全书共5章,第1至3章介绍了PSO算法的原理和各种改进、变体PSO算法的原理,第4章介绍了PSO算法在机械工程领域的应用,第5章介绍了PSO算......一起来看看 《粒子群优化算法及其工程应用》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换