内容简介: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编程无师自通
[美] 科里·奥尔索夫(Cory Althoff) / 宋秉金 / 人民邮电出版社 / 2019-1-1 / 59
畅销Python编程类入门书,美国亚马逊Kindle编程类排行榜榜一。 作者从文科毕业,通过自学编程转行为专业程序员,在硅谷工作多年后成功技术创业。本书不仅教读者如何使用Python语言编程,还会介绍其他书中所忽略的、编程初学者应该了解并掌握的其他所有知识点。 本书作者是一名自学成才的程序员,经过一年的自学,掌握了编程技能并在eBay找到了一份软件工程师的工作。本书是作者结合个人经验写......一起来看看 《Python编程无师自通》 这本书的介绍吧!
HTML 压缩/解压工具
在线压缩/解压 HTML 代码
UNIX 时间戳转换
UNIX 时间戳转换