内容简介: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。
我们在浏览器的控制台也可以很清楚的看到页面的每一个元素(除了单独的文本元素),其实都是一个盒子:
更加详细的介绍可以参考MDN或者W3C规范的描述:
视觉格式化模型
MDN 对其描述如下:
CSS视觉格式化模型(visual formatting model)是用来处理和在视觉媒体上显示文档时使用的计算规则。该模型是CSS的基础概念之一。
视觉格式化模型会根据 CSS盒子模型 将文档中的元素转换为一个个盒子,每个盒子的布局由以下因素决定:
- 盒子的尺寸:精确指定、由约束条件指定或没有指定
- 盒子的类型:行内盒子(inline)、行内级盒子(inine level)、原子行内级盒子(atomic inine-level)、块盒子(block)
- 定位方案(position scheme):普通流定位、浮动定位或绝对定位
- 文档树中的其他元素:即当前盒子的子元素或兄弟元素
- 视口尺寸与位置
- 所包含的图片的尺寸
- 其他的某些外部因素
关于不同类型盒子的介绍,大家可以直接看MDN,写的很详细了,这里就不再阐述。这边着重讲下 定位方案 。
定位方案
一旦生成了盒子,CSS引擎就需要定位它们以完成布局。在定位的时候,浏览器会根据元素的盒类型和上下文对这些元素进行定位,可以说盒就是定位的基本单位。定位时有三种定位方案,分别是:常规流(即普通流)、浮动流以及绝对定位。
常规流(Normal flow)
- 在常规流中,盒子一个接着一个排列;
- 在 块级格式化上下文 里面,它们 竖着 排列;
- 在 行内格式化上下文 里面,它们 横着 排列;
- 当
position为static或relative,并且float为none时,会触发常规流 - 对于 静态定位 (static positioning),
position: static,盒的位置是常规流布局里的位置; - 对于 相对定位 *(relative positioning),
position: relative,盒偏移位置右这些属性定义:top、bottom、left、right。 即使有偏移,仍然保留原有的位置 ,其他常规流不能占用这个位置。
浮动(Floats)
- 盒成为浮动盒(floating boxes);
- 它定位于当前行的开头或末尾;
- 这 导致常规流环绕在它的周边 ,除非设置
clear属性;
绝对定位(Absolute positioning)
- 绝对定位方案, 盒从常规流中被移除 ,不影响常规流的布局;
- 它的定位相对于它的包含块,相关CSS属性:
top、bottom、left、right; - 对于
position: absolute,元素定位相对于最近的一个relative、absolute或fixed的父元素,如果没有则相对于body
FC(Formatting context)
Formatting context是W3C CSS2.1规范中的一个概念。它是页面中一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。最常见的Formatting context有Block formatting context(简称BFC)和Inline formatting context(简称IFC)。
CSS2.1中只有 BFC 和 IFC ,CSS3中还增加了 GFC 和 FFC 。我们主要来讲下 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 -
position为absolute或fixed -
display为inline-block、table-cell、table-caption、flex、inline-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;
}
复制代码
页面截图:
根据 BFC 布局规则第3条:
每个元素的margin box的左边,与包含快border box的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此(除非该盒建立了一个新的块格式化上下文)
即使存在浮动元素 side , main 的左边依然会与包含快的左边相接触。
根据 BFC 布局规则第4条:
BFC 的区域不会与float box重叠
所以,我们可以给 main 创建一个新的 BFC ,这样就不会跟浮动的 side 重叠了,它会根据包含块的宽度和 side 的宽度,自动变窄。
给 main 加上 overflow: hidden
main {
overflow: hidden;
}
复制代码
再来看下效果:
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;
}
复制代码
页面截图:
可以看到,由于子元素设置了浮动,而父元素又没有设置高度,导致父元素高度塌陷了:没有自动被子元素的高度撑开。
根据 BFC 布局规则第6条:
计算BFC的高度时,浮动元素也参与计算
我们可以给父元素 parent 触发 BFC ,那么它在计算高度时,内部的浮动元素也会参与计算。
.parent {
overflow: hidden;
}
复制代码
再看下效果:
3.阻止margin重叠
<div class="box">box</div> <div class="box">box</div> 复制代码
.box {
width: 200px;
height: 200px;
margin: 100px;
background: red;
}
复制代码
页面截图:
根据 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;
}
复制代码
页面截图:
还有很多其他的例子,比如可以避免文字环绕、多列布局等等,这里就不再一一列举,大家有兴趣的可以自己多尝试下,这里有一个网址可以在线演示,更加直观, 链接地址: www.cnblogs.com/xiaohuochai…
创建BFC的新方式
我们上面举的例子都是通过 overflow 来创建 BFC ,但是其实这个方法会有两个问题。
- 这些方法本身是有自身的设计目的的,所以在使用它们创建
BFC时可能会存在一些副作用。例如,使用overflow创建BFC后,在某些情况下可能会看到出现一个滚动条或者元素内容被裁切。这是由于overflow属性的设计是用来让你告诉浏览器如何定义元素的溢出状态的。浏览器执行了它最基本的定义。 - 另一个问题是,即使在没有出现副作用的情况下,使用
overflow也可能会使另一个开发人员感到困惑。他们可能会各种猜想:这里为什么要把overflow的值设为auto或hidden?原来的开发人员这样做的意义是什么?原来的开发人员是想让这里出现滚动条吗?
所以实际项目开发中,还需要根据项目的需求来选择合适的方法,最好也能在代码里写明注释。
那有没有什么更好的方式呢?CSS工作组定义了一个新的属性值: display: flow-root 。
你可以使用 display: flow-root 安全的创建 BFC ,来解决上文中提到的各种问题:自适应两栏布局、清除内部浮动、阻止margin重叠等等。
caniuse上 display: flow-root 在各浏览器的兼容情况,看图:
目前来看,兼容性还是差了一点。
有关于 flow-root 的详细介绍可以看这篇文章: www.w3cplus.com/css3/displa…
BFC概念理解
可以想象一下, BFC 就相当于我们现实中的一个纸箱(盒子),箱子里面的东西的放置(布局)是不会受到外部其他东西的影响的,它形成了一个独立的封闭的区域。当然它里面东西的放置(布局)也不会影响到外面的东西。
最后
感谢您的阅读,希望对你有所帮助,希望你能通过这篇文章能对 BFC 有一个比较全面的理解并能实际应用到项目开发中。本人水平有限,如果文中有不当的地方烦请指正,感激不尽。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 【前端帮帮忙】第5期 关于CSS权重,你了解多少?
- 【前端帮帮忙】第7期 关于节流(throttle)和防抖(debounce)的理解
- 前端科普系列(三):CommonJS 不是前端却革命了前端
- 前端科普系列(三):CommonJS 不是前端却革命了前端
- 前端技术演进(三):前端安全
- 【前端优化】前端常见性能优化
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Python语言程序设计
[美]梁勇(Lang Y. D.) / 李娜 / 机械工业出版社 / 2015-4 / 79.00元
本书采用“问题驱动”、“基础先行”和“实例和实践相结合”的方式,讲述如何使用Python语言进行程序设计。本书首先介绍Python程序设计的基本概念,接着介绍面向对象程序设计方法,最后介绍算法与数据结构方面的内容。为了帮助学生更好地掌握相关知识,本书每章都包括以下模块:学习目标,引言,关键点,检查点,问题,本章总结,测试题,编程题,注意、提示和警告。 本书可以作为高等院校计算机及相关专业Py......一起来看看 《Python语言程序设计》 这本书的介绍吧!