[关闭]
@shenguotao 2017-01-08T23:00:39.000000Z 字数 4073 阅读 2478

BFC 从了解到放弃

BFC clearfix 边距重叠 高度塌陷

最近工作中我突然产生了一个想法,就如我们人类面临的终极问题一般,我从哪里来?我到哪里去?在撸代码进行CSS布局的时候,我会去想,我为什么这么做?,为什么浮动的元素要用overflow?,为什么要用clearfix?,为什么边距会重叠?为什么absolute就不需要clearfix,为什么...


什么是BFC?及其作用!

BFC 即(Block Format Context)快级格式化范围,是 CSS2.1 中用于规定块级盒子的渲染布局方式,他在计算盒子高度,margin值等地方有区别于其他环境。
BFC 是一种概念,是对前端布局技术的一种理论上的总结,掌握它可以让我们在使用CSS +DIV进行布局时,知道一些特殊操作以及规避问题的原理。
形象的去理解我们可以将BFC看做成一个封闭的盒子,盒子以及盒子内的内容不受盒子外的其它盒子所影响,反之亦然。

BFC的主要作用有以下几点:

如何产生BFC?

为下情况都会让元素本身产生BFC环境:

· 根元素 (一个页面的Html标签应该是唯一的)
· display: inline-block | table-cell | table-caption | flex
· position: absolute | fixed
· overflow: hidden | auto | scroll
· float: left | right

BFC的应用

1. 边距重叠

边距重叠对于前端来说是一个很基础的概念了,这里我就简单说下其概念与解决方法,图啊代码什么的,就略了~
所谓边距重叠就是当两个元素垂直边距相互接触时,它们将合并形成一个边距,这个合并后的边距值就是这两个边距值中最大的哪一个。
产生边距重叠的情形无外乎以下两个方面:

解决边距重叠的方法有很多,但是我认为这些方法最终还是归于两种:
防止边距接触
既然边距重叠是发生在边距相互接触的情形下,那么我们就可以针对问题的本质,防止两个元素的边距发生接触,比较常见的方法有:

· border-top:1px solid transparent  
  添加1px透明的上边框,来解决父子元素边距重叠。
· padding-top:1px
  添加1px间距,来解决父子元素边距重叠。
· 添加1px高度的间隔元素
  这种添加冗余标签的方式来解决垂直同级排列的边距重叠,最好还是不要采用。

利用BFC特性
其实,这个才是重点嘛,毕竟本篇文章说的是BFC相关的技能!
不产生边距重叠的效果本来就是BFC的特性之一,只是我们要根据使用场景进行选择。
利用BFC防止边距塌陷:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <style>
  6. div {
  7. width: 300px;
  8. height: 300px;
  9. background: #eee;
  10. margin: 10px;
  11. }
  12. p {
  13. width: 100px;
  14. height: 100px;
  15. background: #aaa;
  16. margin: 20px;
  17. }
  18. .box1 {
  19. overflow: hidden; /* 通过overflow方式形成BFC环境 */
  20. }
  21. .box2 {
  22. display: table-cell; /* 通过display方式形成BFC环境 */
  23. }
  24. .box3 {
  25. position: absolute; /* 通过position方式形成BFC环境 */
  26. }
  27. .box4 {
  28. float: left; /* 通过float方式形成BFC环境 */
  29. margin-top: 320px;
  30. }
  31. </style>
  32. </head>
  33. <body>
  34. <div class="box1"><p>overflow</p></div>
  35. <div class="box2"><p>display</p></div>
  36. <div class="box3"><p>position</p></div>
  37. <div class="box4"><p>float</p></div>
  38. </body>
  39. </html>

不过吧,看了这个DEMO连我自己也感觉通过建立BFC去解决边距重叠有些不太实际,一是有高射炮打蚊子的嫌疑,明明用padding就可以解决的非要去转换元素的类型,非要去overflow,二是通过BFC可能会影响页面的整体排版,毕竟float,absolute有太多的不可控性。

PS:个人认为垂直同级排列的元素边距实际上不需要去防止边距重叠,而且防止的话也很简单,给一个心目中满意的最大值即可。

2.不与float box重叠

我们知道浮动元素会脱离文档流,然后浮盖在文档流元素上,可以见示例:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <style>
  6. .left{
  7. float: left;
  8. width:200px;
  9. height:500px;
  10. opacity:0.5;
  11. background:#eee;
  12. }
  13. .right{
  14. height:500px;
  15. background:red;
  16. }
  17. </style>
  18. </head>
  19. <body>
  20. <div class="left"></div>
  21. <div class="right"></div>
  22. </body>
  23. </html>

当一个元素浮动,另一个元素不浮动时,浮动元素因为脱离文档流就会盖在不浮动的元素上。
解决这个问题的方法也很简单,那就是为非浮动元素建立BFC环境,根据BFC的不不与float box重叠的规则,我们可以得知下面DEMO中的情景。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <style>
  6. .left{
  7. float: left;
  8. width:200px;
  9. height:500px;
  10. opacity:0.5;
  11. background:#eee;
  12. }
  13. .right{
  14. height:500px;
  15. overflow:hidden;
  16. background:red;
  17. }
  18. </style>
  19. </head>
  20. <body>
  21. <div class="left"></div>
  22. <div class="right"></div>
  23. </body>
  24. </html>

这一特性,我认为还是很有用的,特别是应用在两栏布局上,对比我们常规为非浮动元素或非定位元素设置margin来挤开的方法,其优点在于不需要去知道浮动或定位元素的宽度。

3.高度塌陷

普通的文档流元素是无法包含浮动后的元素。
示例:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>BFC</title>
  6. <style>
  7. .box{
  8. border:1px solid #aaa;
  9. }
  10. p{
  11. float: left;
  12. width:50px;
  13. height:50px;
  14. background:#eee;
  15. }
  16. </style>
  17. </head>
  18. <body>
  19. <div class="box">
  20. <p></p>
  21. </div>
  22. </body>
  23. </html>

但是一旦为元素建立BFC环境,那么这个元素就可以识别到浮动元素。
示例:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <style>
  6. .box{
  7. display:inline-block;
  8. *zoom:1;
  9. border:1px solid green;
  10. }
  11. p{
  12. float: left;
  13. width:50px;
  14. height:50px;
  15. background:red;
  16. }
  17. </style>
  18. </head>
  19. <body>
  20. <div class="box"><p></p></div>
  21. </body>
  22. </html>

浮动会导致脱离文档流,从而无法被计算到确切的高度,这种情况我们称之为高度塌陷。
解决高度塌陷的前提就是能识别并包含到浮动元素。而BFC就有这个特性,所以BFC也可以计算浮动元素的高度。
示例:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>BFC</title>
  6. <style>
  7. .box{
  8. border:1px solid #aaa;
  9. overflow:hidden;
  10. }
  11. p{
  12. float: left;
  13. width:50px;
  14. height:50px;
  15. background:#eee;
  16. }
  17. </style>
  18. </head>
  19. <body>
  20. <div class="box">
  21. <p></p>
  22. </div>
  23. </body>
  24. </html>

通过 overflow:hidden将元素转换为BFC,固然可以解决高度塌陷的问题,但是大范围的应用在布局上是肯定是行不通的,毕竟overflow会造成溢出隐藏的问题,特别是与JS交互的效果时。
那有没有一个更好的高度检测方法呢?
答案是有的,就是我们经常用到的clearfix

  1. .clearfix:after{
  2. content:'';
  3. display:table;
  4. clear:both
  5. }
  6. .clearfix{
  7. *zoom:1;/* IE6,7不支持BFC,所以需要通过专有的CSS属性,触发hasLayout。*/
  8. }

但是我认为这种方式与BFC并没有直接的关系,chearfix的方法我个人的理解是,当一个普通流的元素因为其内部元素发生了浮动无法包含到内部元素,而导致高度塌陷时,可以在浮动元素的最下面加一个块级元素,并且该块级元素本身应用了清除浮动属性,又因为块级元素独占一行的本质,所以该元素会掉落在浮动元素的下面,从而间接导致了父元素能够重新获取高度。

总结

看了那么多关于BFC知识的介绍,我个人的感觉是并没有什么卵用啊...知道它,不知道它,我平日的工作该怎么做,还是这么做,代码该怎么撸还是这样撸,要说收获的话,就是对CSS 盒模型有了更深入一点的了解,以及利用BFC在两栏自适应布局上的新发现吧。
好了,洗洗睡去了~,明天要上班了~

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注