BFC浅析
BFC定义
Formatting context(格式化上下文) 是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。
BFC(Block formatting context),直译为“块级格式化上下文”,是一个独立渲染区域,内部的元素布局不受外界的影响,并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。
BFC特性
- 属于同一个BFC的两个相邻容器的上下margin会重叠(重点)
- 计算BFC高度时浮动元素也参于计算(重点)
- BFC的区域不会与浮动容器发生重叠(重点)
- BFC内的容器在垂直方向依次排列
- 元素的margin-left与其包含块的border-left相接触
- BFC是独立容器,容器内部元素不会影响容器外部元素
BFC创建
- float属性不为none
- position属性为absolute或者fixed
- display为inline-block,table-cell,flex,inline-flex
- overflow为hidden,auto,scroll
- html根元素
BFC作用
- 解决相邻盒子之间垂直边距重叠问题
- 清除浮动,解决盒子塌陷问题
- 解决父子元素外边距合并(外边距塌陷)
- 解决浮动环绕文字问题
(1)解决相邻盒子之间垂直边距重叠问题
边距重叠问题:
<code class="hljs language-<!DOCTYPE copyable" lang="<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> .marginBottom, .marginTop { width: 100px; height: 100px; background: red; } .marginBottom { margin-bottom: 20px; } .marginTop { margin-top: 20px; } </style> </head> <body> <div class="marginBottom"></div> <div class="marginTop"></div> </body> </html>
样式类名分别为 .marginBottom和 .marginTop的盒子处于同一个BFC内部,相邻margin会重叠,导致两个盒子之间的margin实际为20px
给 .marginBottom类样式的盒子添加一个.container的壳子,设置.container的overflow为hidden,使得两个原有的两个盒子处于不同的BFC之内,达到去除margin重叠的效果
<code class="hljs language-<!DOCTYPE copyable" lang="<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> .marginBottom, .marginTop { width: 100px; height: 100px; background: red; } .marginBottom { margin-bottom: 20px; } .marginTop { margin-top: 20px; } .container { overflow: hidden; } </style> </head> <body> <div class="container"> <div class="marginBottom"></div> </div> <div class="marginTop"></div> </body> </html>
(2)清除浮动,解决盒子塌陷问题
当一个标准流盒子中所有的子元素都进行了浮动,并且没有给盒子设置高度时,那么这个盒子的整个高度就会塌陷,浮动的子元素高度不计算在父元素内,父元素高度就为0。
<code class="hljs language-<!DOCTYPE copyable" lang="<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> .child { width: 100px; height: 100px; background: red; float: left; } .container { background: yellow; } </style> </head> <body> <div class="container"> <div class="child"></div> </div> </body> </html>
.container的高度为0,给.container的盒子添加overflow:hidden以后触发BFC,可以看到.container有了高度。
<code class="hljs language-<!DOCTYPE copyable" lang="<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> .child { width: 100px; height: 100px; background: red; float: left; } .container { background: yellow; overflow: hidden; } </style> </head> <body> <div class="container"> <div class="child"></div> </div> </body> </html>
(3)解决父子元素外边距合并(外边距塌陷)
外边距合并指的是,当两个垂直外边距相遇时,它们将形成一个外边距。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。 (CSS 外边距合并)
<code class="hljs language-<!DOCTYPE copyable" lang="<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> .child { width: 100px; height: 100px; background: red; margin-top: 20px; } .container { background: yellow; width: 200px; height: 200px; } </style> </head> <body> <div class="container"> <div class="child"></div> </div> </body> </html>
child设置margin-top为20px以后,container和child都一起向上边距增加了20px,而不是child相对container增加20px的间距
给container元素增加overflow触发BFC:
<code class="hljs language-<!DOCTYPE copyable" lang="<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> .child { width: 100px; height: 100px; background: red; margin-top: 20px; } .container { background: yellow; width: 200px; height: 200px; overflow: hidden; } </style> </head> <body> <div class="container"> <div class="child"></div> </div> </body> </html>
(4)解决浮动环绕文字问题
<code class="hljs language-<!DOCTYPE copyable" lang="<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> .box { width: 100px; height: 100px; background: red; float: left; } </style> </head> <body> <div class="box"></div> <div>文字文字文字文字文字文字文字文字文字文文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字</div> </body> </html>
文字环绕box块,第二个元素有部分被浮动元素所覆盖,(但是文本信息不会被浮动元素所覆盖) 如果想避免元素被覆盖,可触发第二个元素的 BFC 特性,在第二个元素中加入 overflow: hidden
<code class="hljs language-<!DOCTYPE copyable" lang="<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> .box { width: 100px; height: 100px; background: red; float: left; } .text { overflow: hidden; } </style> </head> <body> <div class="box"></div> <div class="text">文字文字文字文字文字文字文字文字文字文文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字</div> </body> </html>
总结
BFC与其定义一致,创建一个独立渲染区域,内部的元素布局不受外界的影响;通过这种方式与其他元素进行独立,来达成一些样式效果。