CSS规范中对 BFC 的描述
- 块级格式化上下文(
block formating context
)
浮动,绝对定位元素,非块盒的块容器(不是display:block
的block
)(例如,inline-blocks,table-cells和table-captions
)和overflow
不为visible
的块盒会为它们的内容建立一个新的块格式化上下文
在一个块格式化上下文中,盒(子元素)在竖直方向一个接一个地放置,从包含块(父容器)的顶部开始。两个兄弟盒之间的竖直距离由margin
属性决定。同一个块格式化上下文中的相邻块级盒之间的竖直margin
会合并
在一个块格式化上下文中,每个盒的left外边(left outer edge)挨着包含块的left边(对于从右向左的格式化,right边挨着)。即使存在浮动(尽管一个盒的行盒可能会因为浮动收缩),这也成立。除非该盒建立了一个新的块格式化上下文(这种情况下,该盒自身可能会因为浮动变窄)
MDN 对 BFC 的描述
一个块格式化上下文(block formatting context) 是Web页面的可视化CSS渲染出的一部分。它是块级盒布局出现的区域,也是浮动层元素进行交互的区域。
一个块格式化上下文由以下之一创建:
- 根元素或其它包含它的元素
- 浮动元素 (元素的 float 不是 none)
- 绝对定位元素 (元素具有 position 为 absolute 或 fixed)
- 内联块 (元素具有 display: inline-block)
- 表格单元格 (元素具有 display: table-cell,HTML表格单元格默认属性)
- 表格标题 (元素具有 display: table-caption, HTML表格标题默认属性)
- 具有overflow 且值不是 visible 的块元素,
-
display: flow-root
:让当前元素变成一个BFC(触发BFC),没有其他的任何副作用。避免了不成交。 - column-span: all 应当总是会创建一个新的格式化上下文,即便具有 column-span: all 的元素并不被包裹在一个多列容器中。
- 一个块格式化上下文包括创建它的元素内部所有内容,除了被包含于创建新的块级格式化上下文的后代元素内的元素。
代码示例:
因为儿子是bfc,所以孙子由儿子照,所以爸爸就不管孙子,所以爸爸包不住孙子,但是baba也触发了bfc,所以baba是要包住儿子的。因为儿子的高度写死了。所以才没有包住孙子,想要包住孙子,不要限制高度就可以了。 - 块格式化上下文对于定位 (参见 float) 与清除浮动 (参见 clear) 很重要。定位和清除浮动的样式规则只适用于处于同一块格式化上下文内的元素。浮动不会影响其它块格式化上下文中元素的布局,并且清除浮动只能清除同一块格式化上下文中在它前面的元素的浮动。
BFC的功能:
- BFC没有定义,只有功能特征。
- 功能1:爸爸管儿子。BFC可以清除浮动。
用BFC包住浮动元素(不是清除浮动,.clearfix才是清除浮动。)
以下代码baba
不添加float:eft
就不BFC,就不能包裹住浮动的erzi
。或者添加position: absolute;
或者display: inline-block;
或者overflow: auto;
;display: flow-root
等等。
css不正交:改的东西不是我想要的效果,互相影响。
.baba {
border: 10px solid red;
min-height: 10px;
float:left;
}
.erzi {
height: 100px;
width: 400px;
background: green;
float: left;
}
使用以上的方法会出现一些自己不想要的效果,比如display:inline-block
还虽然触发了BFC,但是还是使元素变成inline-block
了,,但是display: flow-root
可以做到,没有副作用,只是单纯地触发BFC。
- 兄弟之间划清界限
用float + div
做左右自适应布局。felx代替。
一个float:left
+overflow: auto
就可以简单的实现一个左右布局。如果didi
也用float:left
触发BFC,缺点:宽度无法自适应。
<style type = "text/css">
.gege {
width: 100px;
min-height: 600px;
border: 3px solid red;
float: left;
margin-right: 10px;
}
.didi {
overflow: auto;
min-height: 600px;
border: 5px solid green;
}
</style>
</head>
<body>
<div class = "gege">
erds
</div>
<div class = "didi">
123
</div>
</body>
/*如果用float:left;则宽度无法自适应*/
}
代码示例:
可以实现同等效果更好的代码:flex代替
.gege {
background: rgba(255,0,0,0.5);
border: 1px solid rgba(255,0,0,0.5);
width: 200px;
height:600px;
float: left;
margin-right: 10px;
}
.didi {
border: 1px solid green;
background: green;
height: 600px;
flex: 1;
}
body {
display: flex;
}
- 计算baba的高度:
.baba {
background: red;
/* overflow: hidden;不好*/
border-top: 10px solid blue;
}/*触发bfc或者设置border挡住儿子,则红色区域为爸爸的高度*/
.erzi {
height: 100px;
background: rgba(0,255,0,0.5);
margin-top: 100px;
}
/*若没有bfc或者Border阻挡,则儿子的margin-top把爸爸的高度挡住,则高度和儿子绿色的部分一样*/
- 一个块格式化上下文包括创建它的元素内部所有内容,除了被包含于创建新的块级格式化上下文的后代元素内的元素。
<style type = "text/css">
.baba {
border: 10px solid red;
display: flow-root;
}
.son {
width: 300px;
height: 100px; /*son的高度写死了,所以才没有包住sunzi*/
background: aqua;
float: left;
margin-top: 100px;
}
.sunzi {
height: 50px;
width: 100px;
margin-top: 200px; /*baba不会包住孙子,不会管孙子*/
background: blue;
}
</style>
</head>
<body>
<div class = "baba">
<div class = "son son1">
<div class = "sunzi"></div>
</div>
</div>
</body>
bfc和文档流有什么关系:
- bfc说的是一个
div
拥有一些属性后,自己就是一个bfc,所以bfc说的是这个div的特性,并没有说div里面的内容。仅仅是影响外部元素的宽高。 - 使DIV的高度计算方法发生变化,BFC之前只包含文档流元素,BFC之后还包含浮动元素。
- 文档流内联元素从左到右排列,块级元素从上到下排列,排列顺序。
- 如果想触发BFC,必须要写一个有副作用的语句。(CSS的不正交)
- bfc内部的东西不可以出去,外面的东西也不可以进来。
<head>
<meta charset="UTF-8">
<title>demo练习</title>
<style>
.baba {
border: 10px solid red;
min-height: 10px;
overflow: hidden;/*改用idsplay:flow-root,就不会出现副作用*/
position: relative;
}
.erzi {
background: green;
width: 500px;
float: left;
}
.v1 {
position: absolute;
width: 100px;
height: 100px;
top: 30px;
background: grey;
}
</style>
</head>
<body>
<div class = "baba">
<div class = "erzi"></div>
<div class = "v1"></div>
</div>
</body>
- bfc是不好的。