Skip to content
New issue

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 #8

Open
zhaozy93 opened this issue Jun 27, 2017 · 0 comments
Open

BFC #8

zhaozy93 opened this issue Jun 27, 2017 · 0 comments

Comments

@zhaozy93
Copy link
Owner

zhaozy93 commented Jun 27, 2017

BFC

在重新理解块级元素那篇文章中,提到了外边距折叠(也有人称坍塌、合并),在解释折叠原因和解决方案时提到了一个概念叫BFC,因此也单独开一篇来重新理解一下BFC是什么。两篇文章先看哪一篇都可以,也没啥先后顺序和前后基础的关系。

先来一个一个的看概念

Block-level elements are those elements of the source document that are formatted visually as blocks (e.g., paragraphs). The following values of the ‘display’ property make an element block-level: ‘block’, ‘list-item’, and ‘table’.
Block-level boxes are boxes that participate in a block formatting context. Each block-level element generates a principal block-level box that contains descendant boxes and generated content and is also the box involved in any positioning scheme
上面两段内容翻译一下

  • 块级元素是文档中定义的格式化为可视块了的元素。设置display属性为‘block’, ‘list-item’, and ‘table’可以使元素变为块级元素。
  • 块级盒block-level box是参与了块级排版上下文(BFC)的一种盒子。每一个块级元素会产生一个块级盒子,块级盒子它包含子盒子和产生的内容,同时它参与任何排版位置计算。
    从这两段内容我们得出几个结论:
  • 参与排版的是块级盒子block-level box, 而不是block-level element
  • 块级盒子block-level box是由块级元素产生的。

关于block-level box块级盒子,这里就不放示意图了,就是margin、border、padding、context这几个知识点,构成一个block-level box,一搜一大把示意图。

关于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.
In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the ‘margin’ properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.
In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).
还是先翻译一下上面那段内容

  • 浮动、绝对定位、块级容器但不是块级元素(inline-block、table-cells、table-captions)、overflow值不为visible的块级元素会为他们的内容建立新的BFC
  • 在一个BFC中,盒子会一个接一个垂直排列,从包含块的最顶端开始。两个相邻盒子的垂直距离由它们的margin决定,在同一个BFC内,可能会出现外边距折叠现象
  • 在一个BFC中,每一个盒子的左外边会碰到包含块的左内容边(从右向左拍的相反),即使在是浮动元素也是如此(即使一个盒子的行盒是因为浮动而收缩了的),除非这个盒子新建了一个块级排版上下文(在某些情况下这个盒子自身会因为floats而变窄)。

通过这段内容我们似乎能看出来,整个页面的排版首先考虑的是BFC之间的排列,至于像外边距折叠这些东西都是在某个BFC内部才会出现的现象,因此BFC之间的排列才是最重要的。

BFC的排列其实也很简单,就是经常说的

普通流中的块元素独占一行,然后从上往下一个接一个的排布
虽然这句话可能描述的不一定是BFC的排列,但基本是正确的。在普通文档流中,每个块级元素产生一个块级盒子,块级盒子要独占一排,从上到下,左边紧贴父元素排列。

那我们再来看一看经常与BFC一起提到的一个叫外边距折叠的现象。

刚才规定里面都讲到了,在同一个BFC内部才会出现外边距折叠,意味着只要我们重新建立BFC就有可能规避外边距折叠的现象。
这两张图片可以比较好的解释一下,当出现外边距折叠的某一方被一个新的BFC包裹了,那么原本折叠的两方就像不能碰面一样,也就不能发生折叠现象了。
image1
image2

但是,注意刚才用词都是有可能规避,再去看前面翻译的那段也有加重的几个字:他们的内容。 举个例子,两个垂直元素发生折叠,你即使为上面元素设置overflow: hidden也是没有效果的,因为是为他们的内容建立新的BFC,但是它们本身还是在原本的BFC中,所以嘛,还是会折叠!

因此BFC和外边距折叠其实是两码事,只是很多情况下,新建一个BFC可以解决外边距折叠这个问题而已,仅此而已。

position、display、float叠加

其实这块内容放在这里多少有些突兀,也有点不太合适,不过恰好就是看到了、恰好就是任性。
image3
这张图片也告诉了我们position、display、float共同设置时的效果。除去各自本身单独设置时产生的效果不谈,它们共同设置的时候,就像有优先级一样,会产生一些属性的遮蔽效果。

设定值 转换后
inline-table table
inline, run-in, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block block
其他 不转换

这部分的是从前人blog中看到,通过最后链接可以查看详细的解释,但基本的概念与平时使用也差不多。

  • display: none 就像开关一样,控制一切
  • 当设置了absolute、fixed之后,元素便像块级元素一样,飞了起来。float被忽略
  • 其余position才会有float的展现余地。
  • 都没有设置的情况下,只能来看display了。。。。

总结

  • 触发BFC的不是特殊元素,BFC只是部分元素的一种属性
  • 从html结构来看,其与BFC一点关系都没有,BFC仅仅是存在于CSS的布局的一种方式。
  • BFC与普通容器也没有根本区别,只是BFC产生了一个独立的区域(矩形),BFC内的元素不会影响外界,外界也不会影响到BFC内部。
  • BFC有一些普通容器没有的特性,比如可以包含浮动元素,因此可以通过触发BFC来解决父级容器高度塌陷的问题。
  • IE低版本可以使用zoom:1来触发hasLayout, 其与BFC基本相似。

references

@zhaozy93 zhaozy93 mentioned this issue Jun 27, 2017
@zhaozy93 zhaozy93 mentioned this issue May 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant