BFC概念与特性
BFC的全称是Block formatting context,直接翻译是块级格式化上下文,我喜欢把它翻译成上下文无关区域,这可能更接近它的含义,具体地说
BFC指的是页面的一个独立的渲染区域,它有自己的布局规则,其内的元素和区域外的元素互不干扰
除了内外元素相互不影响之外,BFC还存在一些独特的特性
首先,BFC不与浮动盒子重叠,并且BFC内部的浮动元素参与BFC的高度计算,从这两点特性可以看出,构建BFC是一个很好的清除浮动的手段,将包含浮动元素的父元素构建成为一个BFC可以有效地解决塌陷的问题
然后,BFC内部的块盒和行盒(行内所有元素构成行盒)会垂直沿着父元素的边框排列,相邻元素的margin会发生重叠,你可能会觉得这好像跟在body里写的排布规则是一样的,因为html根元素本身就是一个BFC
BFC触发机制
满足以下任一条件即可形成BFC
- body 根元素
- 浮动元素 (float: left/right,如果是inherit则需要继承属性非none)
- 绝对定位元素 (position: absolute/fixed)
- 特定布局方式 (display: inline-block/flex/table-cells)
- 溢出设置非visible (overflow: hidden/auto/scroll)
BFC用途
浮动相关
父元素塌陷问题
首先我们从特性中就可以得到一点,BFC可以很好地清除浮动,父级元素触发BFC,可以防止塌陷
塌陷的意思就是,当子元素浮动的时候,不能正常地将父元素撑开,比如下面这段代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <style> .son { height: 100px; width: 100px; float: left; background-color: yellow; } .father{ background-color: pink; width: 200px; border: 1px solid black; } </style> <body> <div class="father"> <div class="son"> </div> </div> </body>
|
实现的效果如下图
如果我们让父元素成为bfc
1 2 3 4 5 6
| .father{ background-color: pink; width: 200px; border: 1px solid black; overflow:hidden; }
|
就可以解决子元素浮动时父元素的塌陷问题
浮动元素覆盖问题
浮动元素是脱离文档流的,因此会和文档流元素出现重叠的情况
比如下列代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <style> .b1 { height: 100px; width: 100px; float: left; background-color: yellow; } .b2{ background-color: pink; width: 200px; height: 200px; } </style>
<body> <div class="b1"></div> <div class="b2"></div> </body>
|
会产生如下效果
一个比较好的解决方案就是,将不希望被覆盖的元素触发BFC,使得其上下文无关 (把float盒子挤出去)
边距设置
相邻元素的间距
在文档流中,相邻元素间的margin是会重叠的,比方说,我们上下两个盒子各自设置了100px的外边距,实际上页面中两个盒子之间的距离并不会是200px而是100px
如果希望两个盒子的外边距是互不影响的,那么我们需要做的事情就是将这两个盒子放入两个相邻的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 25 26
| <style> .b1 { height: 100px; width: 100px; background-color: yellow; margin: 100px; } .b2{ background-color: pink; width: 100px; height: 100px; margin: 100px; } .bfc{ overflow: hidden; } </style>
<body> <div class="bfc"> <div class="b1"></div> </div> <div class="bfc"> <div class="b2"></div> </div> </body>
|
父子元素margin重叠
在垂直方向上,父子元素的margin也是会重叠的,比如在子元素设置一个margin,则父元会共用这个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 25
| <style> .b0{ height: 100px; width: 300px; background-color: brown; } .b1 { height: 100px; width: 100px; background-color: yellow; } .b2{ background-color: pink; width: 50px; height: 50px; margin: 25px; } </style>
<body> <div class="b0"></div> <div class="b1"> <div class="b2"></div> </div> </body>
|
这简直就是浏览器解析设计中的bug,不过好在我们有方法解决这个问题
如果我们希望这个margin设置的是子元素和父元素的距离,则需要将父元素变为BFC