CSS块级格式化上下文是块级盒子的一种能力,这种能力并不是直接通过css属性声明而获得的,而是添加css的一部分相关属性之后自动获得的能力,也就是说没有一个明确的属性就是生成块级格式化上下文的。
块级格式化上下文的能力就是让具有该能力的盒子可以隔绝盒子内外的环境,盒子内部的布局不会影响到盒子外部,同样盒子外部也不会影响到盒子内部。
那么,没有格式化上下文的盒子怎么样才能被盒子外部影响或者说怎么样才能影响到盒子外部呢?这个后面再说,我们先来看下块级格式化上下文有哪些规定。
- 在块级格式化元素(下面简称BFC元素)内部块级元素(下面简称box)在垂直方向一个接一个摆放(这个不言自明,块级元素都是在垂直方向一个接着一个摆放的,即使不是BFC元素的子元素)
- box左外边距紧挨块级元素border-left,即使存在浮动(同上)
- box间的垂直距离由margin-top/bottom决定,会发生垂直外边距折叠(同上)
- BFC元素计算高度的时候会将float的子元素计算在内(BFC元素不会因为因为float的子元素引起高度塌陷,发现了清除浮动)
- BFC元素内部不会影响到外部的布局(指的是子元素的垂直外边距不会和父元素的垂直外边距折叠。不是BFC的元素没有上下padding和border的情况下会和子元素的垂直margin发生折叠)
- BFC元素不会和float元素重叠(我们都知道元素float起来之后,该元素后面的兄弟元素会移动到float元素原来的位置,被float元素覆盖,但是float元素不会被覆盖,但是也不是垂直排列,而是与float并排显示,只是收缩自身给float元素腾出了位置。发现一个两列自适应布局的方式)
好看完了BFC的规定继续上面的问题。
在布局中有两种布局方式会有意料之外的表现,并且可以用块级格式化上下文来解决:
- 元素浮动造成父元素高度塌陷
- 相邻元素之间垂直外边距发生折叠
浮动元素引起的父元素高度塌陷
<style>
.wrap{background: #e77918;
}.l{width: 200px;height: 100px;float: left;background: #ccc;
}
</style><body><div class="wrap"><div class="l"></div></div>
</body>
这就是浮动元素引起的父元素高度塌陷,父元素的背景颜色并没有展示出来。
为 .wrap
加上 overflow: hidden;
之后形成了 块级格式化上下文,盒子内部的布局并不会影响盒子外部,所以盒子的高度不会塌陷。
相邻元素之间垂直外边距发生折叠
<style>
</style>
<body><p>段落一</p><p>段落二</p>
</body>
p标签的默认垂直外边距就会发生折叠,段落一的下外边距和段落二的上外边距发生了折叠。这样就是段落一和段落二的垂直距离不是两个外边距之和而是取两个钟较大的。
让两个p元素分别在不同的BFC中就不会形成外边距折叠。
<style>div{overflow: hidden;}
</style>
<body><div><p>段落一</p></div><div><p>段落二</p></div>
</body>
#使用BFC实现两栏布局
在BFC中,每个盒子的左外边框紧挨着包含块的左边框(从右到左的格式,则为紧挨右边框)。即使存在浮动也是这样的(尽管一个盒子的边框会由于浮动而收缩),除非这个盒子的内部创建了一个新的BFC浮动,盒子本身将会变得更窄)。
<style>*{margin: 0;padding: 0;}.l{float: left;}.nofloat{background: red;color: #fff;}p{padding: 10px 0;}
</style>
<body><div><p class="l">浮动</p><p class="nofloat">本段落未浮动</p></div>
</body>
为 .nofloat 加上 overflow: hidden 形成 BFC 之后。
这就是两栏布局,.nofloat
盒子是自适应的。
怎么形成块级格式化上下文
通过上文知道可以使用 overflow: hidden;
让盒子具有BFC属性,除了 overflow: hidden;
还有以下CSS属性可以形成BFC
-
position不为 relative 和 static
-
display为inline-block、table-cell、table-caption、flex、inline-flex中任何一个
-
overflow不为visible
-
float不为none