块级格式化上下文

这一生的挚爱 提交于 2020-01-10 02:56:32

块级格式化上下文听说过多次,自己也去看了许多文章,但自己总是觉得晦涩,搞不清楚,后来又再去查了下很多文章,终于觉得自己理解一些了,希望自己描述出来能够准确和易懂。

Formatting context

Formatting context 是页面的一个渲染区域,它有着自己的渲染规则,决定渲染区域里面的元素怎么定位,以及里面的元素之间的相互作用。而块级格式化上下文(Block fomatting context)是其中的一种渲染规则。

渲染规则

  1. 渲染区域内的盒子(块级盒子)会在里面垂直放置。
  2. 盒子的垂直方向的距离由margin决定,而且相邻的盒子之间的margin会重叠。
  3. Block fomatting context区域内的元素从渲染区域最左边开始排列(如果是从左往右的格式化的话,从右往左就是最右边开始排列),即使是浮动也如此。
  4. Block fomatting context区域不会与浮动的元素重叠。
  5. Block fomatting context区域是与外面隔离的,不会影响到外表面的元素,外面也不会影响到里面。
  6. 如果触发Block fomatting context渲染规则的话,浮动元素也参与计算渲染区域的高度。

以下是从css2.1规范中文版中截取的一段文字,希望对阅读有帮助:
在这里插入图片描述

触发块级格式化上下文的条件

  • 根元素。
  • 浮动的元素(属性不为none)。
  • 绝对定位的元素、固定定位的元素。
  • 非块级元素的块容器,display为inline-block, table-cell, table-caption, flex, inline-flex。
  • overflow不为visible( hidden,scroll,auto)的块级盒子。

可能的疑问

1.块级元素和块级格式化上下文

块级元素(如div,p标签)是元素,而块级格式化上下文是一种渲染规则。例:
在这里插入图片描述
上面这段代码,bfc盒子没有触发块级格式化上下文,渲染结果如下:
在这里插入图片描述
可以看出它没有触发块级格式化上下文:

  • 从渲染规则 2 看,两个子盒子的margin没有重叠。
  • 从渲染规则 6 看,浮动的盒子没有参与父盒子的高度计算。

如果恢复 /* display: inline-block; */ 让 bfc 盒子触发块级格式化上下文,结果如下:
在这里插入图片描述
可以看到 bfc 盒子的高度改变了,验证了渲染规则6 ,浮动的盒子也会参与块级格式化上下文的高度计算。

仔细观察的你可能注意到规则 2 没有触发,也就是外边距合并问题没有发生。为什么?

  • 这是因为 box2 中的 float 会让 box2 创建一个新的块级格式化上下文(请看块级格式话上下文触发条件)。

为什么创建新的块级格式化上下文就解决了外边距合并问题?

  • 还记得渲染规则 5 吗?块级格式化上下文元素内外互不影响。你可以理解为,box1 的 margin-bottom 挤下来了 box2 创建的块级格式化上下文,而这个块级格式化上下文的范围是 box2 的大小。那么外边距合并问题就不存在了。

BFC 通常解决的问题

  1. 用来实现自适应两栏布局。
    在这里插入图片描述
    结果
    这里有两点,第一点是渲染规则 3 ,从最渲染区域内最左边开始,box1 浮动起来,不属于标准流,但仍从区域内最左边开始排列。box2 在标准流,也从最左边开始排列。接下来是第二点,渲染规则 4 和 5,4 不会和浮动的重叠和 5 内外是隔离的,box1 就不会遮住 box2 的内容。

  2. 解决父盒子在子元素浮动之后没有高度的问题。
    从原理看就是渲染规则 6 ,浮动元素也参与高度计算。你可能通常是使用 overflow: hidden; 来触发。

  3. 防止外边距合并
    从原理看是渲染规则 5 ,内外是隔离的,解决外边距合并问题。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!