BFC
BFC(Block Formatting Context),块级格式上下文。
What is BFC ?
BFC 是一块渲染的区域。在这之前,有一块区域叫做 FC 它是默认浏览器支持的渲染区域。
FC:浏览器默认支持的多个盒子之前的排列规则。
BFC:区别于默认浏览器的多个盒子之间的排列规则。
默认 FC 规则
我们先举例,什么是默认的 FC 规则,这样的规则有什么坏处。
外边距塌陷
垂直方向上,当我们设置两个盒子之间都有margin的时候:
这与我们想要达到的效果不一致,默认BF盒子排列规则:
两个盒子之间的距离是:(上方盒子的marginBottom + 下方盒子的magrinTop) / 2
浮动子元素父元素的宽高丢失
我们再看一个默认 BF 规则,当同时 float 多个元素的时候。
当我们查看 DIV#Container 他的宽度为 0,父元素的宽度和高度都已经丢失了;
我们常见的方式是用 清除浮动 来解决,当然,我们也可以采用生成BFC的方式解决。
浮动元素与非浮动元素重叠
当在父元素之内,有两个兄弟元素,一个元素浮动,另一个元素不浮动,就会产生一种状况:
你能够很明显地看到,两个兄弟元素发生了堆叠,应该如何解决呢?
我们常用的方式是,将 DIV#blue 也设置为向左浮动,然后用父元素清除浮动;
这样就能够保证父元素的宽度不会丢失,两个元素也不会发生堆叠,另外BFC可以解决这个问题。
使用 BFC 解决以上问题
BFC 的规则就是为了解决 BF 遗留下来的问题,当兄弟盒子上下或左右排列时产生的问题。
生成一个 BFC 规则盒子
- 根元素或包含根元素的元素
- 浮动元素(元素的 float 不是 none)
- 绝对定位元素(元素的 position 为 absolute 或 fixed)
- 行内块元素(元素的 display 为 inline-block)
- 表格单元格(元素的 display为 table-cell,HTML表格单元格默认为该值)
- 表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)
- 匿名表格单元格元素(元素的 display为 table、table-row、 table-row-group、- table-header-group、table-footer-group(分别是HTML table、row、tbody、- thead、tfoot的默认属性)或 inline-table)
- overflow 值不为 visible 的块元素
- display 值为 flow-root 的元素
- contain 值为 layout、content或 strict 的元素
- 弹性元素(display为 flex 或 inline-flex元素的直接子元素)
- 网格元素(display为 grid 或 inline-grid 元素的直接子元素)
- 多列容器(元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1)
- column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。
此规则来源于:块格式化上下文 - Web开发者指南 | MDN;
我们无法记住这么多内容,当我们遇到上面的几个问题时,查看BFC文档,然后就可以解决。
解决:外边距塌陷
这里我们采用 overflow: hidden;
来解决这样的问题。
第一步:我们给 #blue
盒子,添加了一个 #blueBox
的盒子包裹;
第二步:我们将 #blueBox
的盒子,使用overflow: hidden;
,触发BFC渲染。
第三步;解决外边距塌陷的问题。
解决:浮动子元素父元素的宽高丢失
这里我们采用 overflow: hidden;
来解决这样的问题。
第一步:我们将父元素 DIV#Container
设置为 overflow: hidden;
生成BFC的排列规则。
第二步:DIV#Container
就是一个拥有BFC规则的盒子。
解决:浮动元素与非浮动元素重叠
这里我们采用 overflow: hidden;
来解决这样的问题。
我们设置 DIV#blue
元素为 overflow: hidden;
,它就成为了一个拥有BFC规则的盒子。
实战:利用BFC完成一份流式网格布局
我们经常会使用 boostrap
等网格系统;
在这里,我根据 skeleton.css
改编,简单完成一份这样的布局结构。
从而,是我们更加深刻地理解,BFC在实际场景中的应用。
浮动的栅格化布局
ONE
ELEVEN
TWO
TEN
THREE
NINE
FOUR
EIGHT
FIVE
SEVEN
SIX
SIX
SEVEN
FIVE
EIGHT
FOUR
NINE
THREE
TEN
TWO
ELEVEN
ONE
这是基本的页面结构,我们将整体划为12份,根 bootstrap.css
的思维一致。
body {
font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 12px;
}
.Container {
position: relative;
width: 100%;
margin: 0 auto;
padding: 0 20px;
box-sizing: border-box;
-moz-box-sizing: border-box;
overflow: hidden; /* 触发 BFC 规则,避免子元素浮动后的父元素失去宽和高 */
}
.row {
overflow: hidden; /* 触发 BFC 规则,避免子元素浮动后的父元素失去宽和高 */
}
.column,
.columns {
width: 100%;
float: left; /* 触发 BFC 规则 */
box-sizing: border-box;
font-weight: 400;
letter-spacing: .1rem;
margin-bottom: 1%;
background-color: #CCC;
height: 30px;
line-height: 30px;
text-align: center;
border-radius: 5px;
}
.column:first-child,
.columns:first-child {
margin-right: 4%;
}
.one.column,
.one.columns { width: 4.66666666667%; }
.two.columns { width: 13.3333333333%; }
.three.columns { width: 22%; }
.four.columns { width: 30.6666666667%; }
.five.columns { width: 39.3333333333%; }
.six.columns { width: 48%; }
.seven.columns { width: 56.6666666667%; }
.eight.columns { width: 65.3333333333%; }
.nine.columns { width: 74.0%; }
.ten.columns { width: 82.6666666667%; }
.eleven.columns { width: 91.3333333333%; }
.twelve.columns { width: 100%; margin-left: 0; }
.one-third.column { width: 30.6666666667%; }
.two-thirds.column { width: 65.3333333333%; }
上文中,有多处应用到了BFC的影子,在这里,我就不过多阐述了。
参考文章
- [我对BFC的理解][https://www.cnblogs.com/dojo-lzz/p/3999013.html]