BFC
参考资料:MDN: Block formatting context
什么是 BFC
BFC(Block Formatting Context,块格式化上下文)是 Web 页面中可视的 CSS 渲染的一部分,它是块盒子布局时所在的区域,该区域中的浮动元素与其他元素相互作用(即清除浮动的作用)。
我的理解:就是页面中的一个渲染区域,该区域是块级的,并且该区域中的浮动元素不影响其它 BFC 中元素的布局(所以该特性经常被用来清除浮动)。
BFC就是一个独立不干扰外界也不受外界干扰的盒子
BFC 规则
- 内部的Box会在垂直方向,一个一个地布置。
- Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的Margin会发生重叠,也就是外边距塌陷。
- 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- BFC的区域不会与float box叠加。
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
- 计算BFC的高度时,浮动元素也参与计算。
创建BFC :
- 根元素
<html>
- float的值不为none
- overflow的值不为visible
- display的值为inline-block、table-cell、table-caption
- position的值为absolute或fixed
BFC的应用
1、自适应两栏布局
2、清除内部浮动
3、防止margin上下重叠(解决margin叠加问题)
自适应两栏布局
左边固定,右边自适应
为.main元素的样式加上overflow:hidden;使其建立一个BFC,让其内容消除对外界浮动元素的影响。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <style> .container { width: 100%; position: relative; } .aside { width: 100px; height: 150px; float: left; background-color: #f66; } .main { height: 200px; background-color: #fcc; overflow: hidden; } </style> </head> <body> <div class="container"> <div class="aside"></div> <div class="main"></div> </div> </body>
|
清除浮动,计算BFC的高度
我们都知道浮动会脱离文档流,接下来我们看看下面的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <style> .box1{ width:100px; height:100px; float:left; border: 1px solid #000; } .box2{ width:100px; height:100px; float:left; border: 1px solid #000; } .box{ background:yellow } </style> <body> <div class="box"> <div class="box1"></div> <div class="box2"></div> </div> </body>
|
由于容器内两个div元素浮动,脱离了文档流,父容器内容宽度为零(即发生高度塌陷),未能将子元素包裹住。解决这个问题,只需要把把父元素变成一个BFC就行了。常用的办法是给父元素设置overflow:hidden
。
父级添加overflow属性,通过触发BFC的方式,清除浮动效果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <style> .box1{ width:100px; height:100px; float:left; border: 1px solid #000; } .box2{ width:100px; height:100px; float:left; border: 1px solid #000; } .box{ background:yellow; overflow: hidden; } </style> <body> <div class="box"> <div class="box1"></div> <div class="box2"></div> </div> </body>
|
解决margin叠加问题
按照BFC的定义,只有同属于一个BFC时,两个元素才有可能发生垂直margin的重叠,这个包括相邻元素或者嵌套元素,只要他们之间没有阻挡(比如边框、非空内容、padding等)就会发生margin重叠。
①相邻兄弟元素margin重叠问题
| <style> p { color: #fff; background: #888; width: 200px; line-height: 100px; text-align: center; margin: 100px; } </style> <body> <p>ABC</p> <p>abc</p> </body>
|
上面例中两个P元素之间距离本该为200px,然而实际上只有100px,发生了margin重叠。遇到这种情形,我们如何处理?
只需要在p外面包裹一层容器,并触发该容器生成一个BFC。那么两个P便不属于同一个BFC,就不会发生margin重叠了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <style> p { color: #fff; background: #888; width: 200px; line-height: 100px; text-align: center; margin: 100px; } .wrap { overflow: hidden; } </style> <body> <p>ABC</p> <div class="wrap"> <p>abc</p> </div> </body>
|
②父子元素margin重叠问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <style> .box { width: 100px; height: 100px; background: #ccc; } .wrap { background: yellow; } .wrap h1 { background: pink; margin: 40px; } </style> <body> <div class="box">box</div> <div class="wrap"> <h1>h1</h1> </div> </body>
|
wrap元素与h1元素之间理论上本该有个40px的上下margin值,然而实际上父子元素并没有存在margin值,与此同时,两个div元素的间距为40px。遇到这种情形,我们如何处理?
处理方法其实有很多,在wrap元素中添加:overflow:hidden;或者overflow:auto;使其父元素形成一个BFC;也可以在wrap元素中添加border:1px solid;或是padding:1px,这些都可以有效解决父子元素margin重叠问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <style> .box { width: 100px; height: 100px; background: #ccc; } .wrap { background: yellow; border: 1px solid; } .wrap h1 { background: pink; margin: 40px; } </style> <body> <div class="box">box</div> <div class="wrap"> <h1>h1</h1> </div> </body>
|