We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BFC(Block Formatting Context),中文翻译为“块格式化上下文”。它有一个明显的特性,那就是如果一个元素拥有了 BFC 特性,那么它内部元素不受外部元素的影响,外部元素也不会受其内部元素的影响。
但到底什么才是 BFC 呢?
先来看看 MDN 对 BFC 的解释。
块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,是布局过程中生成块级盒子的区域,也是浮动元素与其他元素的交互限定区域。
下列方式会创建块格式化上下文:
根元素或包含根元素的元素 浮动元素(元素的 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)。
创建了块格式化上下文的元素中的所有内容都会被包含到该BFC中。
块格式化上下文对浮动定位(参见 float)与清除浮动(参见 clear)都很重要。浮动定位和清除浮动时只会应用于同一个BFC内的元素。浮动不会影响其它BFC中元素的布局,而清除浮动只能清除同一BFC中在它前面的元素的浮动。外边距折叠(Margin collapsing)也只会发生在属于同一BFC的块级元素之间。
感觉怎么样?反正我读下来的感觉就是:
好像也没具体的说什么是 BFC 。
个人感觉 BFC 就像女孩子的好感一样,没法说清楚什么才算是女孩子对你有好感,但是一旦女孩子对你有好感,你就知道了。
BFC 同理,没法说清楚什么是 BFC ,但是当 BFC 一出现,你就知道那个东西属不属于 BFC ,也就是拥有某些特定属性的东西就是 BFC ,能触发 BFC 的属性 MDN 上都有说明。
BFC 元素里面元素不能影响外面的元素,利用这个特性,可以用来管住子元素。
我们知道,当一个元素变成浮动元素后,那么它就会脱离文档流,对页面布局产生影响,利用 BFC 就可牢牢管住浮动元素,消除这种影响,
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>BFC</title> </head> <body> <div class="father"> <div class="child"></div> </div> </body> <style> .father { width: 300px; border: 1px solid red; } .child { width: 200px; height: 100px; background: pink; } </style> </html>
从动态图中可以看到,当我们给child元素加一个浮动时,它就会脱离father元素的掌控,如果这时候把father元素变成 BFC (float: left;、 display: inline-block; 都可以将元素变成 BFC 元素,其他更多方法看 MDN 的解释),那么child元素就会重新被father元素所掌控。
child
father
float: left;
display: inline-block;
对于清楚浮动,也可以利用clearfix来实现,这个更推荐clearfix,因为 BFC 有副作用,除了display: flow-root之外,其他将元素变成 BFC 的都是给元素加了一个其他的属性,这就会造成副作用。
clearfix
display: flow-root
display: flow-root是一个专门生成 BFC 的一个属性,但是它是一个高级属性,浏览器支持不全面。
当我们给子元素一个margin时,它的margin部分会跑到父级元素外面去。
margin
当给子元素加一个margin-top: 100px;后,会发现子元素比父元素大了,这个时候把父级元素变成 BFC 后,父级元素又会重新把子元素包进来。
margin-top: 100px;
BFC 元素外面的元素不能影响其里面的元素,利用这个特性可以和兄弟元素划清界限,不受兄弟元素的影响。
我们知道,在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。
而当其中一个元素变成了 BFC 之后,里面的子元素就不会与这个元素的相邻元素发生外边距叠加。
来看例子。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>BFC</title> </head> <body> <div class="child"></div> <div class="father"> <div class="child"></div> </div> <div class="child"></div> </body> <style> .father{ } .child{ width: 200px; height: 100px; background: pink; margin: 20px; } </style> </html>
这时候会发生外边距叠加,它们中间的边距为20px。如果存在 BFC ,就会与旁边的元素划清界限,也就不会发生外边距叠加了。
20px
从代码及动态图可以看到,其实是father元素里面的child元素与father元素的兄弟元素发生了外边距叠加,当father元素变成 BFC 后,里面的child元素与father元素的兄弟消除了外边距叠加。
我们来看另外一种情况,看下面的动态图。
从图中可以看到,BFC 元素本身不会与其兄弟元素消除外边距叠加,它只能消除其子元素与 BFC 兄弟元素之间的外边距叠加。
我们知道当兄弟元素变成浮动元素后,它就会“骑”在我们身上,这我们肯定不能忍啊。那咋办呢?把我们自己变成 BFC 就好了。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>BFC</title> </head> <body> <div class="father"> <div class="child1"></div> <div class="child2"></div> </div> </body> <style> .father{ width: 350px; background: #999; } .child1{ float: left; width: 100px; height: 200px; background: pink; } .child2{ display: flow-root; width: 200px; height: 300px; background: red; } </style> </html>
那我想离这个想压迫我的兄弟远点那怎么办?我们自然而然地想到了margin-left,来试试margin-left: 20px;,来看看效果。
margin-left
margin-left: 20px;
咦?咋没用呢?来看看它的margin。
原来兄弟元素虽然不能压迫我们自身,但它仍旧可以“骑”在我们的外边距上。正所谓 BFC 的一个特性:外部元素不能影响 BFC 内部元素,但没说外部元素不能影响 BFC 元素本身。
既然这样,那就加大力度,我来个margin-left: 120px。
margin-left: 120px
这下倒是与兄弟元素分开了,但有一个很大的缺点,当兄弟元素的宽度发生变化时,它们之间的间距也发生了变化,如果想要其间距固定怎么办?
我们换个思路,把margin写在浮动元素上怎样?
从动态图中可以看到,当margin写在浮动元素上后,不管其宽度怎么变,与兄弟 BFC 元素总会有着固定的间隔。
利用这个特性,我们能完成一个多栏的布局。
文章中如有错误之处,忘不吝赐教。
参考资料:
https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context
https://www.zhangxinxu.com/wordpress/2015/02/css-deep-understand-flow-bfc-column-two-auto-layout/#comment
The text was updated successfully, but these errors were encountered:
No branches or pull requests
1 引言
BFC(Block Formatting Context),中文翻译为“块格式化上下文”。它有一个明显的特性,那就是如果一个元素拥有了 BFC 特性,那么它内部元素不受外部元素的影响,外部元素也不会受其内部元素的影响。
但到底什么才是 BFC 呢?
先来看看 MDN 对 BFC 的解释。
2 MDN 对 BFC 的解释
感觉怎么样?反正我读下来的感觉就是:
好像也没具体的说什么是 BFC 。
3 BFC 的个人理解
个人感觉 BFC 就像女孩子的好感一样,没法说清楚什么才算是女孩子对你有好感,但是一旦女孩子对你有好感,你就知道了。
BFC 同理,没法说清楚什么是 BFC ,但是当 BFC 一出现,你就知道那个东西属不属于 BFC ,也就是拥有某些特定属性的东西就是 BFC ,能触发 BFC 的属性 MDN 上都有说明。
4 BFC 的用处
4.1 管住子元素
BFC 元素里面元素不能影响外面的元素,利用这个特性,可以用来管住子元素。
4.1.1 浮动元素
我们知道,当一个元素变成浮动元素后,那么它就会脱离文档流,对页面布局产生影响,利用 BFC 就可牢牢管住浮动元素,消除这种影响,
从动态图中可以看到,当我们给
child
元素加一个浮动时,它就会脱离father
元素的掌控,如果这时候把father
元素变成 BFC (float: left;
、display: inline-block;
都可以将元素变成 BFC 元素,其他更多方法看 MDN 的解释),那么child
元素就会重新被father
元素所掌控。对于清楚浮动,也可以利用
clearfix
来实现,这个更推荐clearfix
,因为 BFC 有副作用,除了display: flow-root
之外,其他将元素变成 BFC 的都是给元素加了一个其他的属性,这就会造成副作用。display: flow-root
是一个专门生成 BFC 的一个属性,但是它是一个高级属性,浏览器支持不全面。4.1.2 margin
当我们给子元素一个
margin
时,它的margin
部分会跑到父级元素外面去。当给子元素加一个
margin-top: 100px;
后,会发现子元素比父元素大了,这个时候把父级元素变成 BFC 后,父级元素又会重新把子元素包进来。4.2 和兄弟划清界限
BFC 元素外面的元素不能影响其里面的元素,利用这个特性可以和兄弟元素划清界限,不受兄弟元素的影响。
4.2.1 清除外边距叠加
我们知道,在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。
而当其中一个元素变成了 BFC 之后,里面的子元素就不会与这个元素的相邻元素发生外边距叠加。
来看例子。
这时候会发生外边距叠加,它们中间的边距为
20px
。如果存在 BFC ,就会与旁边的元素划清界限,也就不会发生外边距叠加了。从代码及动态图可以看到,其实是
father
元素里面的child
元素与father
元素的兄弟元素发生了外边距叠加,当father
元素变成 BFC 后,里面的child
元素与father
元素的兄弟消除了外边距叠加。我们来看另外一种情况,看下面的动态图。
从图中可以看到,BFC 元素本身不会与其兄弟元素消除外边距叠加,它只能消除其子元素与 BFC 兄弟元素之间的外边距叠加。
4.2.2 打破兄弟浮动元素的压迫
我们知道当兄弟元素变成浮动元素后,它就会“骑”在我们身上,这我们肯定不能忍啊。那咋办呢?把我们自己变成 BFC 就好了。
那我想离这个想压迫我的兄弟远点那怎么办?我们自然而然地想到了
margin-left
,来试试margin-left: 20px;
,来看看效果。咦?咋没用呢?来看看它的
margin
。原来兄弟元素虽然不能压迫我们自身,但它仍旧可以“骑”在我们的外边距上。正所谓 BFC 的一个特性:外部元素不能影响 BFC 内部元素,但没说外部元素不能影响 BFC 元素本身。
既然这样,那就加大力度,我来个
margin-left: 120px
。这下倒是与兄弟元素分开了,但有一个很大的缺点,当兄弟元素的宽度发生变化时,它们之间的间距也发生了变化,如果想要其间距固定怎么办?
我们换个思路,把
margin
写在浮动元素上怎样?从动态图中可以看到,当
margin
写在浮动元素上后,不管其宽度怎么变,与兄弟 BFC 元素总会有着固定的间隔。利用这个特性,我们能完成一个多栏的布局。
文章中如有错误之处,忘不吝赐教。
参考资料:
https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context
https://www.zhangxinxu.com/wordpress/2015/02/css-deep-understand-flow-bfc-column-two-auto-layout/#comment
The text was updated successfully, but these errors were encountered: