BFC全称Block Formatting Context ,中文直译为块级格式上下文。它是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。
一.BFC触发条件(参考MDN):
下列方式会创建块格式化上下文: 根元素() 浮动元素(元素的 float 不是 none) 绝对定位元素(元素的 position 为 absolute 或 fixed) 行内块元素(元素的 display 为 inline-block) 表格单元格(元素的 display为 table-cell,HTML表格单元格默认为该值) 表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值) 匿名表格单元格元素(元素的 display为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table) overflow 值不为 visible 的块元素 display 值为 flow-root 的元素(创建无副作用的BFC,像overflow:hidden;等其他触发BFC的代码,也会同时产生本身的效果,比如溢出的部分隐藏. 这些效果 有时候我们是不需要的,所以可以使用display:flow-root 来触发 BFC) contain 值为 layout、content或 paint 的元素 弹性元素(display为 flex 或 inline-flex元素的直接子元素) 网格元素(display为 grid 或 inline-grid 元素的直接子元素) 多列容器(元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1) column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。
二.BFC的布局规则
在BFC下,内部的Box会在垂直方向,一个接一个地放置。
Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box 的margin会发生重叠(外边距合并) 有前置条件margin必须是邻接的. 邻接的概念: 1.必须是处于常规文档流(非float和绝对定位)的块级盒子,并且处于同一个BFC当中。 (所以解释了 浮动和定位能解决 外边距合并) 2.没有线盒,没有空隙(clearance,下面会讲到),没有padding和border将他们分隔开
垂直外边距合并的情况 1.父子级关系的盒子,顶部外边距合并(也叫塌陷) 2.父子级关系的盒子,父盒子高度auto时,底部外边距合并 3.兄弟级关系的盒子,上面盒子的底部外边距和下面盒子的顶部外边距的合并
前两种情况对父盒子触发BFC,即可将父盒子的外边距和子盒子的外边距隔开,不再同一个BFC内,即可解决合并的问题. 第三种情况可以对下面的盒子设置浮动,根据邻接的定义,从而解决边距合并问题
在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘),即使存在浮动也是如此。
BFC的区域不会与float box重叠。(行内块元素和文字的环绕效果的解释)
计算BFC的高度时,浮动元素也参与计算(over-hidden清除浮动的解释)
三.关于clearance 理解的clearance:对浮动元素之后的元素设置clear以闭合相关方向的浮动时即设置clear:both;之后,闭合浮动的元素会在其margin-top以上产生一定的空隙,这段空隙叫做clearance,clearance的高度撑起了 父元素的高度.(clear-both清除浮动的本质,用clearance的高度撑起了父盒子)
1.在clear:both之后,产生的clearance的高度等于浮动元素高度 2.clear:both 清除掉 当前元素前面相邻的兄弟级浮动元素对当前元素的影响 这句话是根据资料里面找的,有点疑问,如果是宽度固定的父盒子,高度由清除浮动后的clearance来撑开,里面浮动的子元素因为宽度换行了,但是clearance仍能按两个浮动元素的高度来撑开父盒子,那这句话是不是表达的不是很对,正确的一个解释应该是什么呢?