我所理解的BFC

CSS任何的排版都是有原因的,都是可以解释的,这篇文章主要是介绍关于BFC的概念,内容循序渐进,希望能被理解和接受

1.  对CSS有了解的道友们肯定都知道盒式模型这个概念,对一个元素设置CSS,首先需要知道这个元素是block还是inline类型,但是无论这个元素是什么类型,但是它们都是BOX概念的体现,关于CSS中BOX的概念:
Box是CSS布局的基本单位
Box 是 CSS 布局的对象和基本单位, 直观点来说,就是一个页面是由很多个 Box 组成的,元素的类型和 display 属性,决定了这个 Box 的类型, 不同类型的 Box, 会参与不同的 Formatting Context(一个决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染。让我们看看有哪些盒子:
a)block-level box:display 属性为 block, list-item, table 的元素,会生成 block-level box。并且参与 block fomatting context;
b)inline-level box:display 属性为 inline, inline-block, inline-table 的元素,会生成 inline-level box。并且参与 inline formatting context;

PS: 页面中的html标签被浏览器解析后,生成的元素将被添加到document tree中,但是CSS作用的对象并不是document tree, 而是根据document tree 生成的render tree,而盒子模型就是render tree的节点,  因此需要注意的有:
1 CSS作用的是盒子(BOX),而不是元素(Element)
2 JS无法直接操作盒子
3 行级盒子模型和块级盒子模型结构一致,只是行级盒子模型在此基础上有自身特性而已。
4. 对于盒子的组成而言,有四个部分,分别为content box, padding box, border box, margin box

2.  理解了上面的基础知识后,就可以学习什么是 Formatting Context
Formatting Context 页面中的一个渲染区域,并且该区域拥有一套渲染规则,这套渲染规则决定了其子元素如何定位,以及与其他元素的相互关系和作用。 (CSS2.1 中只有 BFC 和 IFC, CSS3 中还增加了 GFC 和 FFC)
简单来说,FC就是页面上的一块渲染区域, 最常见的 Formatting context 有 Block fomatting context (BFC)和 Inline formatting context (IFC)

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

2)  如何让一块区域具有BFC的渲染规则:既然上文提到BFC是一块渲染区域,那这块渲染区域到底在哪,它又是有多大,这些由生成BFC的元素决定,CSS2.1中规定满足下列CSS声明之一的元素便会生成BFC。
(1)根元素(html、body)
(2)float的值不为none(left, right)
(3)overflow的值不为visible(hidden, scroll, inherit, auto..)
(4)display的值为inline-block、table-cell、table-caption
(5)position的值为absolute或fixed

具体的,BFC的约束规则如下面的描述(浏览器对于BFC这块区域的约束规则如下):
(1)能满足条件形成BFC渲染区域元素的子元素(block-level box)会一个接一个的放置。垂直方向上他们的起点是一个包含块的顶部(一个矩形),两个相邻子元素之间的垂直距离取决于元素的margin特性。在BFC中相邻的块级元素外边距会折叠。
(2)能满足生成BFC元素的子元素中,每一个子元素的外边距与包含块的左边界相接触,(对于从右到左的格式化,右外边距接触右边界),即使浮动元素也是如此(尽管子元素的内容区域会由于浮动而压缩),除非这个子元素也创建了一个新的BFC(如它自身也是一个浮动元素)。

上面的描述具有高度的抽象性,不是很容易理解,将它拆分如下成更加细致化的BFC布局规则(切记下面布局的基础是block-level box):
a)具有BFC渲染区域的元素内部的Box(block level)会在垂直方向,一个接一个地放置。
b)具有BFC渲染区域的元素内部的Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
c)每个子元素(具有BFC渲染区域的元素内部的子元素)的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
d)BFC的区域不会与float box重叠(这个特性的前提条件是对同一层级的BFC渲染区域和浮动元素对应生成的BFC渲染区域)。
e)BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素(我们往往利用这个特性来消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响。)。反之也如此。
f)计算BFC的高度时,浮动元素也参与计算(这个特性的前提条件是对父级的BFC渲染区域和子浮动元素对应生成的BFC渲染区域在计算父元素高度时,需要包含子浮动元素的高度才可以,这样才能避免影响到该BFC外部区域)

上面的几个就是细致的BFC布局规则的拆分,可以尝试和下面的一些常用的布局规则对照一下来体会:
Block元素会扩展到与父元素同宽,所以block元素会垂直排列
垂直方向上的两个相邻DIV的margin会重叠,而水平方向不会(此规则并不完全正确)
浮动元素会尽量接近往左上方(或右上方)
为父元素设置overflow:hidden或浮动父元素,则会包含浮动元素
...........................

3. margin collapse,上面提到了一个外边距合并的问题,这就是所谓的margin collapse, 具体的细节如下:
1. 合并外边距与BFC:在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。
2. 折叠的结果
两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
两个外边距一正一负时,折叠结果是两者的相加的和。

3. 产生折叠的必备条件:margin必须是邻接的!而根据w3c规范,两个margin是邻接的必须满足以下条件:
(所谓的折叠的前提是在具有BFC渲染区域的内部的block-level Box)
(1)必须是处于常规文档流(非float和绝对定位)的块级盒子,并且处于同一个BFC当中。
(2)没有线盒,没有空隙(clearance,下面会讲到),没有padding和border将他们分隔开
(3)都属于垂直方向上相邻的外边距,可以是下面任意一种情况
a) 元素的margin-top与其第一个常规文档流的子元素的margin-top(子父关系,也即是具有BFC的盒子和内部的第一个block-level Box)
b) 元素的margin-bottom与其下一个常规文档流的兄弟元素的margin-top(兄弟关系BFC盒子内部的block-level box之间)
c) height为auto的元素的margin-bottom与其最后一个常规文档流的子元素的margin-bottom(子父关系,也即是具有BFC的盒子和内部的第一个block-level Box)
d) 高度为0并且最小高度也为0,不包含常规文档流的子元素,并且自身没有建立新的BFC的元素的margin-top和margin-bottom

4. 以上的条件意味着下列的规则

创建了新的BFC的元素(例如浮动元素或者'overflow'值为'visible'以外的元素)与它的子元素的外边距不会折叠
浮动元素不与任何元素的外边距产生折叠(包括其父元素和子元素)
绝对定位元素不与任何元素的外边距产生折叠
inline-block元素不与任何元素的外边距产生折叠
一个常规文档流元素的margin-bottom与它下一个常规文档流的兄弟元素的margin-top会产生折叠,除非它们之间存在间隙(clearance)。
一个常规文档流元素的margin-top 与其第一个常规文档流的子元素的margin-top产生折叠,条件为父元素不包含 padding 和 border ,子元素不包含 clearance。
一个 'height' 为 'auto' 并且 'min-height' 为 '0'的常规文档流元素的 margin-bottom 会与其最后一个常规文档流子元素的 margin-bottom 折叠,条件为父元素不包含 padding 和 border ,子元素的 margin-bottom 不与包含 clearance 的 margin-top 折叠。
一个不包含border-top、border-bottom、padding-top、padding-bottom的常规文档流元素,并且其 'height' 为 0 或 'auto', 'min-height' 为 '0',其里面也不包含行盒(line box),其自身的 margin-top 和 margin-bottom 会折叠。

我所理解的BFC_第1张图片

你可能感兴趣的:(前端开发基础指南)