初识块级格式化上下文(Block Formatting Contexts)
前言
html文档中元素的定位有3种方式(普通流、绝对定位、浮动),除普通流以外,浮动与绝对定位都会导致元素脱离普通流,按照各自的方式进行定位。
带有BFC属性的容器属于普通流的一种。
块级格式化上下文 (BFC)
块格式化上下文是页面 CSS 视觉渲染的一部分。它是用于决定块盒子的布局及浮动相互影响范围的一个区域。
BFC是元素在拥有某些特定属性才显示的一种属性,有BFC特性的元素和其他普通流中的元素在样式上没有区别。但在功能上,具有BFC的容器内部与外部隔离,即容器内部的元素不会再布局上影响外部元素。
有BFC属性的容器可以包含浮动元素、会阻止外边距折叠、可以阻止元素被浮动元素覆盖。
如何触发BFC
满足下面任意一个条件的元素会触发BFC:
- 根元素或其它包含它的元素
- 浮动 (元素的 float 不为 none)
- 绝对定位元素 (元素的 position 为 absolute 或 fixed)
- 行内块 inline-blocks (元素的 display: inline-block)
- 表格单元格 (元素的 display: table-cell,HTML表格单元格默认属性)
- 表格标题 (元素的 display: table-caption, HTML表格标题默认属性)
- overflow 的值不为 visible的元素
- 弹性盒 flex boxes (元素的 display: flex 或 inline-flex)
以上是 MDN 上引发BFC属性的条件。
需要注意的是,”display:table” 本身并不产生 BFC,而是由它产生匿名框,匿名框中包含 “display:table-cell” 的框会产 BFC。 总之,对于 “display:table” 的元素,产生 BFC 的是匿名框而不是 “display:table”。
BFC特性
1. BFC可以包含浮动元素
通常,浮动的元素会脱离普通流,不仅会影响兄弟元素,也会影响父容器以及父容器兄弟元素。对于父容器,最直观的就是会使父容器高度塌陷
给父容器添加overflow:hidden属性,使其引起BFC属性.
2. 阻止外边距折叠
两个相连的 div 在垂直上的外边距会发生叠加。
详细的解释:仅当两个块级元素相邻并且在同一个块级格式化上下文时,它们垂直方向之间的外边距才会叠加。也就是说,即便两个块级元素相邻,但当它们不在同一个块级格式化上下文时它们的边距也不会折叠。因此,阻止外边距折叠只需产生新的 BFC 。
这里父容器的上下设置了20px的外边距,而p元素有1em的上下外边距。可以看到第一个p元素与父容器顶部没有间距,两者外边距产生重叠。
父容器添加overflow:hidden属性,使其引起BFC属性.这里仅第一个p元素与父容器的外边距未折叠,p元素之间外边距折叠。
将中间的p元素用一个div包裹,并添加overflow:hidden属性,使其引起BFC属性.
3. 阻止元素被浮动元素覆盖
上面说过,浮动元素会对兄弟元素造成影响。若兄弟元素是块级元素,则会与浮动元素重叠,位于浮动元素之下。若为内联元素,则依次从左至右排列。
但是若子元素display:inline-block,则子元素宽度之和大于父容器宽度,则最后宽度相加超过父容器宽度的子元素换行显示。
BFC处理浮动
通常我们清除浮动,方法有几种:
-
- 设置空div
在父容器末尾添加空div,并设置clear:both清除浮动。这样很方便,但违背结构与表象分离的原则。
-
- 设置overflow
虽然设置其他属性也能引发BFC属性,但会对布局造成一些影响。设置overflow:hidden的影响相对较小,但在子元素的过大时,超出部分会被覆盖掉,设置auto或scroll又会产生滚动条。
-
- :after伪元素
通过为容器添加:after伪元素,并给伪元素设置overflow属性,添加IEhack,实现清除浮动。也是网上使用比较多的方法。
.clearfix{(*zoom: 1;}
.clearfix:after{content:”;height:0;display:block; clear:both;/overflow:hidden; /*clear,overflow二选其一*/}
IE6、7下的BFC
由于早期IE6、7对于不支持BFC,所以需要通过IEhack解决。在IE6、7中,通过触发hasLayout私有属性实现BFC效果。从使用上看,hasLayout私有属性和BFC触发方式都是通过特有属性触发,IE6、7中大多通过设置zoom:1;触发,zoom用于设置或检索元素缩放比例,值1表示元素实际尺寸,所以设置1不会对元素显示造成影响。