参考:
CSS定位的三种机制:普通流、绝对定位和浮动
外边距塌陷之clearance
前端精选文摘:BFC 神奇背后的原理
CSS学习笔记——深入理解BFC
浅析BFC及其作用
BFC概念:
块格式化上下文(Block Formatting Context,BFC)
它是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。
通俗的来说:BFC是一个独立的布局环境,我们可以理解为一个箱子(实际上是看不见摸不着的),箱子内部的元素无论如何翻江倒海,都不会影响到外部。
转换为BFC的理解则是:BFC中的元素的布局是不受外界的影响(我们往往利用这个特性来消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响。)
并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。
BFC布局规则:
1. 在BFC下,内部的Box会在垂直方向,一个接一个地放置。
2. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
3. 在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)
(对于从右到左的格式来说,则触碰到右边缘),即使存在浮动也是如此。
4. BFC的区域不会与float box重叠。
5. 计算BFC的高度时,浮动元素也参与计算
触发 BFC 的条件如下:
1.浮动元素,float 除 none 以外的值
2.绝对定位元素,position(absolute,fixed)
3.display 为以下其中之一的值inline-block, table-cell, table-caption, flex,inline-flex,grid,inline-grid
4.overflow 除了 visible 以外的值(hidden,auto,scroll)
BFC 的一些用处
(如清浮动,防止 margin 重叠等)
合并外边距与BFC
在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。
这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。
折叠结果:
1. 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
2. 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
3. 两个外边距一正一负时,折叠结果是两者的相加的和。
普通流、绝对定位和浮动
1.普通流(Normal Flow)
在普通流中,元素按照其在 HTML 中的先后位置至上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行,块级元素则会被渲染为完整的一个新行, 除非另外指定,否则所有元素默认都是普通流定位,也可以说,普通流中元素的位置由该元素在 HTML 文档中的位置决定。
2.浮动 (Float)
在浮动布局中,元素首先按照普通流的位置出现,然后根据浮动的方向尽可能的向左边或右边偏移,其效果与印刷排版中的文本环绕相似。
3.绝对定位 (Absolute Positioning)
在绝对定位布局中,元素会整体脱离普通流,因此绝对定位元素不会对其兄弟元素造成影响,而元素具体的位置由绝对定位的坐标决定。
浮动和绝对定位不与任何元素产生 margin 折叠
inline-block元素与其兄弟元素、子元素和父元素的外边距都不会折叠(包括其父元素和子元素)
inline-block不符合w3c规范所说元素必须是块级盒子的条件,
因为规范中又说明,块级盒子的display属性必须是以下三种之一:’block’, ‘list-item’, 和 ‘table’。
参考:
BFC 主要有三个特性:
(1) BFC 会阻止外边距折叠
两个相连的 div 在垂直上的外边距会发生叠加,有些书籍会把这个情况列作 bug ,这里 Kayo 并不同意,这种折叠虽然会给不熟悉 CSS 布局的开发者带来一些不便,但实际上它具有完整且具体的折叠规则,并且在主流浏览器中都存在,因此 Kayo 更认为这应该是 CSS 的特性。当然,在实际开发中,或许我们有时会不需要这种折叠,这时可以利用 BFC 的其中一个特性——阻止外边距叠加。
(2) BFC 可以包含浮动的元素
这也正是上面使用 overflow: hidden 与 overflow: auto 方法闭合浮动的原理,使用 overflow: hidden 或 overflow: auto 触发浮动元素父元素的 BFC 特性,从而可以包含浮动元素,闭合浮动。
W3C 的原文是“’Auto’ heights for block formatting context roots”,也就是 BFC 会根据子元素的情况自动适应高度,即使其子元素中包括浮动元素。
但是 IE6-7 并不支持 W3C 的 BFC ,而是使用自产的 hasLayout 。从表现上来说,它跟 BFC 很相似,只是 hasLayout 自身存在很多问题,导致了 IE6-7 中一系列的 bug 。触发 hasLayout 的条件与触发 BFC 有些相似,具体情况 Kayo 会另写文章介绍。这里 Kayo 推荐为元素设置 IE 特有的 CSS 属性 zoom: 1 触发 hasLayout ,zoom 用于设置或检索元素的缩放比例,值为“1”即使用元素的实际尺寸,使用 zoom: 1 既可以触发 hasLayout 又不会对元素造成其他影响,相对来说会更为方便。
(3) BFC 可以阻止元素被浮动元素覆盖
如上面所说,浮动元素的块状兄弟元素会无视浮动元素的位置,尽量占满一整行,这样就会被浮动元素覆盖,为该兄弟元素触发 BFC 后可以阻止这种情况的发生。
为了说明 BFC 对于清除浮动的本质,Kayo 在这里使用了较大的篇幅介绍了 BFC ,但 BFC 并不是本文要说明的中心,并且 BFC 的机制也相当复杂,因此 Kayo 会基于以上 BFC 的内容另写一篇更详细的文章介绍 BFC ,并制作 Demo 说明实际情况。