资讯专栏INFORMATION COLUMN

BFC的一些探究

curlyCheng / 1358人阅读

摘要:它是用于决定盒子的布局及浮动相互影响范围的一个区域。小白反思如果世界的运行都有自我运行的一套机制,那么的世界必然有自己的一套规则。外边距合并当时在回答外边距的问题时,总结出了合并的一条规则必须相邻。

最初的梦

了解BFC后,能够更深入的明白外边距合并原理
了解BFC后,能够更深入的明白浮动的行为
了解BFC后,知识就是你的,总不会吃亏对吧?哈哈

之前有两篇文章《行内元素的一些探索》、《浮动的一些探索》,或多或少隐式的牵连到了块级格式化上下文

今天正式介绍BFC,以加深对CSS的理解。

-------------写在前面---------------
BFC是时候表演真正的技术了之前的内容是参考MDN的块级格式化上下文和自我思考的过程组成,今日重读感觉糟糕之极,于是便在此给出w3c规范中的定义以作补充。

W3C规范中是这样定义BFC的:

Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with "overflow" other than "visible" (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.

这里需要注意的几个点block containersblock boxestheir contents

浮动、绝对定位元素,非块级盒子的块级容器(比如display属性值为inline-block,tale-cells和table-captions的元素),以及overflow属性设置为visible以外的块级盒子都为它们的内容创建了新的块级格式化上下文。

原文在这
block formatting context

彻底了解w3c规范BFC的定义后可以直接阅读最后一部分内容(bfc是时候表演技术)

BFC的生理构造 BFC外衣

块级格式化上下文(block formatting context)是页面CSS视觉渲染的一部分。它是用于决定盒子的布局及浮动相互影响范围的一个区域BFC之间不会相互影响。

小白反思

一共三句话。
第一句话忽略不计。

第二句话很关键。不过先反问下,这句话里的盒子指的是谁,也就是说决定谁的浮动和布局?

这个问题的答案其实很简单,这里的盒子指代的是产生BFC元素块级子元素

反思:什么条件产生BFC,决定谁的布局?
解答:BFC的产生见下文。块级格式化上下文(BFC)从字面上理解应该能推测出盒子指代的是块级子元素

第三句话也很重要。BFC之间不会相互影响,那么BFC和其它的元素会发生影响,BFC中的元素和其它的元素会发生影响嘛?

答案是肯定的,BFC和其它元素会发生影响,但BFC中的元素不会受其它元素影响。

反思:这里的其它元素指的是什么元素?
解答:处在同一个包含块中同级别(互为兄弟关系)的元素。

BFC的心

官方外衣总是华丽,值得琢磨,尽管仔细思考了也必然有所获。但,作为程序员,怎能不去了解她的心。

块级格式化上下文包括了创建该上下文的元素的所有子元素,但不包括创建了新的块格式化上下文的子元素。

小白反思

如果世界的运行都有自我运行的一套机制,那么BFC的世界必然有自己的一套规则。世界的运行总避免不了能力超凡者打破规矩、突破限制形成另一个世界并不再受之前的约束。这里的能力超凡者就可以理解为创建了新的块级格式化上下文的元素。那么如果获得创造新世界的能力呢?

BFC,你是怎么来到这个世界的?

世界从来都不是平等的,或许就像海贼王里的天龙人,高高在上。BFC有些元素与生俱来,有些就靠开发者来赋予。

根元素或其它包含它的元素

浮动和定位元素(设置了float不为none或position不为relative和static)

overflow不为visible的元素

display设为inline-block、table-cell和table-caption

新的世界,总会形成一套自己的规矩。

BFC的游戏规则

在BFC中,盒子从顶端开始垂直地一个接一个排列,两个盒子之间的垂直间隙是由他们的margin值决定

同一个BFC中,两个相邻块级盒子的垂直外边距会产生重叠

在BFC中,每一个盒子的左边缘都会触碰到容器到左边缘

计算BFC元素高度时,浮动元素也参与计算

BFC是时候表演真正的技术了 文字环绕

这是一种常见的现象。有些时候,实际需要的效果是下面这样的。

为了直观的看到BFC的作用,给段落p添加个背景色。


清晰看见p的行框有一部分是在绿色透明块之下的,现在赋予p元素BFC的话,那么浮动的Div和p就相当于超强者(各自形成自己的BFC),根据BFC之间互不影响这一特性。效果就是下面这样的。

外边距合并

当时在回答div外边距的问题时,总结出了合并的一条规则:margin必须相邻。但当时只探究了margin合并的条件,却未曾探究条件的产生(什么情况才算相邻)。现在从BFC的角度重聊这个话题。

margin相邻的前提条件

必须处于文档正常流块级盒子,并且处于同一个BFC

没有线盒,没有清除区域(clearance),没有padding和border

margin都是垂直方向上的

针对第一点,进行一个简单的说明。


这是常见的外边距合并。触发合并的因素符合相邻的前提条件。
代码如下




    

一般情况阻止外边距重叠会给父元素Div.parent设置overflow:hidden。

那么如果给Div.child设置overflow:hidden呢?

.child{width:200px;height:200px;margin:30px 0;background:#f3a;overflow:hidden;}

怎么会这样?Div.child不是产生了新的BFC吗?那么Div.parentDiv.child就不在同一BFC中了。那么不是违背了margin相邻的前提条件中的第一条了吗?为什么还发生重叠了?

反思:重叠既然发生了,说明一个问题,那就是margin相邻的条件全部满足了。这说明Div.parentDiv.child处在同一个BFC,overflow:hidden设置给父元素时确实发生作用并产生了新的BFC,并阻止重叠。
overflow:hidden设置给子元素时也确实作用并产生新BFC,但却没阻止重叠。

说到这,需要考虑的问题就是BFC概念了。
BFC的心这一节里有提BFC的内部组成。这里再次引用:

块级格式化上下文包括了创建该上下文的元素的所有子元素,但不包括创建了新的块格式化上下文的子元素。

一句话概括:BFC是为其内容而生的。

BFC不包括产生BFC的元素,也就是不包括生产者!

overflow:hidden设置给父元素时,阻断了重叠发生。这说明Div.parentDiv.child不处在同一个BFC中。child处在parent产生的BFC中,而parent处在最开始的BFC中。所以重叠不发生。

overflow:hidden设置给子元素时,重叠发生。这说明Div.parentDiv.child处在同一个BFC中。child产生的BFC并不会把child自己也纳入进去,而是作用于child的子元素。因此parent和child依然处于同一个BFC中,所以重叠发生。

小白提问
考虑下Div.parent和Div.child多带带设置display:inline-block时,会发生什么现象?

答案或许是这样的,和overflow一样呗。
实践才出真理。
无论是给父元素还是子元素设置display:inline-block,重叠都不会发生。为什么呢?不都是产生了BFC吗?

小白揭秘
margin相邻前提条件的第一条里是要求必须是块级盒子,而在w3c规范中规定,块级盒子的display属性必须是以下三种之一:"block", "list-item", 和 "table"。display:inline-block不在其列,因而无论给谁设置display都不满足条件。所以重叠不发生。

clearance对外边距的影响

下面代码中的margin-top方向为什么没有产生下移的视觉效果,而margin-left方向居然产生了左移的效果。




    

这个问题困惑了我很久。浅谈个人对该问题的理解:
在阅读前,最好深入margin属性。如果不愿意看的话,那就直接看下面这段话吧。

在 margin 中 top、right、bottom、left 的参考线并不一致为一类,而是分为了两类参考线。top 和 left 的参考线属于一类,right 和bottom 的参考线属于另一类。top 以 containing blockcontent 上边或者垂直上方相连元素 margin 的下边为参考线垂直向下位移;left 以 containing blockcontent 左边或者水平左方相连元素 margin 的右边为参考线水平向右位移。right 以元素本身的 border 右边为参考线水平向右位移;bottom 以元素本身的border 下边为参考线垂直向下位移。

小白分析
这段话首先将trbl分成了两类。
其中top和left的参考线又分为两种。

container block content top(left)
top和left分别对应父元素content top edgecontent left edge

sibling margin-bottom (margin-right)
top和left分别对应相邻元素margin-bottommargin-right(这里当然会发生margin collapse)

bottom和right是以元素自身border-bottom(border-right)为边界。

问题剖析
1.margin-left发生了水平偏移,且child在水平方向并没有相邻元素,这说明其参考是父元素(section)的content left edge
2.margin-top没发生偏移,这至少说明其参考线不是父元素(section)的content top edge。然而在垂直方向上,child是拥有一个相邻的东西(clearance),那么很明显就是clearance捣鬼。如果clearance被解析成盒模型了,那么垂直方向肯定能产生位移,如果解析成其他一些东西了,那么没有位移就很正常了。 (这一点也模糊,希望有人指点)

w3c clearance

两列布局,我来讲点不一样的

两列布局的要求:
一栏宽度固定一栏宽度随浏览器发生改变

以下最常见的代码,没有任何问题。




    
    
This is main content

换个思路实现两列布局,各位看官看好喽。




    
This is main content

这里做了三处修改

将main与aside的位置交换

为main添加右浮动,改变aside浮动方向,并显式设置了width:100%

为main添加了margin-left:-200px;

这样看上去是没有任何一点问题的。

如果向main里添加更多的文字会发生什么?

那么第一种两列布局会不会发生上面这种情况呢?

你真的懂BFC了吗?

小白解析

第一种布局之所以不会发生重叠,是因为它们在同一个BFC中

第二种布局之所以会重叠,是因为它们在不同BFC中

圣杯、双飞翼,我也来玩

问题产生




    
I am boss

基本描述:此时给中间绿色块div填写内容会出现重叠现象,原理同上述两列布局

为了解决这个问题,出现两种思路(或许双飞翼是圣杯的优化方案)

圣杯好像很好吃的样子~




    
I am boss

以上就是圣杯布局。分析就不写了。直接看双飞翼布局吧,非常精妙的布局。




    
I am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am bossI am boss

小白分析
首先在不考虑使用position:relative的情况下,要达到圣杯布局的效果,那只能通过margin来作用。先贴张问题图方便阅读

那么直接给main(绿色的div)添加margin: 0 100px 0 250px;不就行了吗?


由上述两张图可知道margin属性只有左边的发生作用了,而右边的未发生作用。这是因为属性过分受限(overconstrained),将margin-right强制设为auto了。(调试器看不出来的)

因此该思路不可行。

于是便思索通过水平格式化这一idea来实现。

给main套一层div.wrap-main

将main的部分属性(float、width)移到div.wrap-main,并为main添加margin: 0 100px 0 250px;

至此,双飞翼布局已经实现。

涉及知识点总结

水平格式化

属性过分受限(overconstrained)

margin属性深入了解

bfc的深入认识

float的深入了解

最后一点小收获


这张图应该很有印象吧,前面有哟。

为什么这里有个空白?aside.right在哪里呢?

尽管main的margin-right水平受限被设置为auto,但在计算和渲染时,100px仍然会发生作用。所以aside.left的margin-left:-100%不是靠着最左边而是间隔了100px。受其影响,aside.right的margin-left:-100px就把自己藏在了最左边(下图的位置)。
以上纯属个人理解

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/115021.html

相关文章

  • 探究:绝对定位没有设置 top, right, bottom, left 世界是怎样

    摘要:一个元素如果设置了但没有设置此元素的位置在哪在涉及到绝对定位元素的位置问题时一个重要的概念是想要了解元素的位置还得找到此元素的才行如下是我进行的一系列测试以及对测试结果的试探性解释文中的英文术语都不翻译方便直接查或者其他技术文档请持有怀疑精 一个元素如果设置了position: absolute;, 但没有设置top, right, bottom, left, 此元素的位置在哪? 在涉...

    kbyyd24 评论0 收藏0
  • 解剖CSS布局原理

    摘要:前言本文将带你重新认识布局,带你解剖布局原理,前提是你要有基础本文将解除你在布局方面的疑惑。以下将对布局元素和文档流进行详细讲解。而且还能保持文档流,这是其他元素做不到的。 前言 本文将带你重新认识CSS布局,带你解剖布局原理,前提是你要有基础!本文将解除你在布局方面的疑惑。认识每个布局元素,了解他们的特性,你才知道为什么会是这样的结果。本文内容纯属个人理解,不代表官方。 此文主要为理...

    李文鹏 评论0 收藏0
  • 理解CSS中层叠上下文和层叠顺序

    摘要:后来居上当元素的层叠水平一致层叠顺序相同的时候,在流中处于后面的元素会覆盖前面的元素。相关连接深入理解中的层叠上下文和层叠顺序层叠顺序探究分层的显示 什么是层叠上下文(stacking context) 可以理解为一个dom节点在Z轴高人一等,特性类似于BFC,即层叠上下文的内部子元素再怎么翻江倒海,翻云覆雨都不会影响外部的元素。 CSS2创建层叠上下文的两种方法(参考MDN) 根元...

    Bryan 评论0 收藏0
  • 理解 CSS 布局和 BFC

    摘要:布局中有一些概念,一旦你理解了它们,就能真正提高你的布局能力。我们通常有两种方法来解决这个布局问题。是布局中的一个迷你布局你可以将看作是页面内的一个迷你布局。理解浏览器如何布置网页是非常基础的。 CSS布局中有一些概念,一旦你理解了它们,就能真正提高你的 CSS 布局能力。本文是关于块格式化上下文(BFC)的。你可能从未听说过这个术语,但是如果你曾经用CSS做过布局,你可能知道它是什么...

    miya 评论0 收藏0
  • CSS: 潜藏着BFC

    摘要:而就潜藏在其中,当你修改样式时,一不小心就能触发它而毫无察觉,因此没有意识到的神奇之处。实例解决侵占浮动元素的问题我们知道浮动元素会脱离文档流,然后浮盖在文档流元素上。 在写样式时,往往是添加了一个样式,又或者是修改了某个属性,就达到了我们的预期。而BFC就潜藏在其中,当你修改样式时,一不小心就能触发它而毫无察觉,因此没有意识到BFC的神奇之处。 一、什么是BFC(Block Form...

    learn_shifeng 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<