CSS里的BFC和堆叠上下文
首先声明这篇文章是方便自己查概念时用的,完全不了解这两个概念的人应该会读不懂 :p
之所以将它俩总结在一起,是因为它们的特征非常相似:BFC和堆叠上下文都不是看得见摸得着的实例,而是一套抽象的规则。当你在css里写出一些东西时就会触发这套规则,然后根据BFC或堆叠上下文的规则来渲染页面。
换句话说,知道BFC和堆叠上下文时页面会发生什么,然后知道怎样去触发这两套规则,我们就可以利用它们了。
1.BFC
BFC(Block formatting context)直译为"块级格式化上下文",它是一个独立的渲染区域,在此区域内有一套渲染规则,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。所以说block-level 的box本身就遵循BFC规则。display为block/item-list/table 的元素就是Block-level box。inline,inline-block,inline-table这些都是inline-level box。
那么BFC的渲染规则是什么呢?
- 内部的Box会在垂直方向,一个接一个地放置。
- Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
- 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- BFC的区域不会与float box重叠。
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算BFC的高度时,浮动元素也参与计算
什么叫触发BFC?
根据上述,我们已经知道了在一个页面中,只要是box-level的box都遵循bfc规则,实际上根元素<html></html>就触发了bfc,页面上所有的元素都是这个bfc区域内的子元素而已。所谓的触发bfc,指的是让某一个box变成bfc的父元素,其内部的元素遵循bfc的规则,不过它的外部就和其他元素不相干了。
哪些元素会触发BFC?
- 根元素
- float属性不为none
- position为absolute或fixed
- display为inline-block, table-cell, table-caption, flex, inline-flex
- overflow不为visible
至于BFC的作用,可以清除浮动,阻止外边距合并,布局。当然不到万不得已不要这么做。
2.堆叠上下文
方老师灵魂画图揭示了堆叠顺序的概念:
- background
- border
- 块级
- 浮动
- 内联
- z-index: 0
-
z-index: +
如果是兄弟元素重叠,那么后面的盖在前面的身上。
堆叠顺序
z-index:0的元素一定z-index:-1的上面吗?不一定。如果元素触发了堆叠上下文,其z-index属性将会受到影响。
具体如何触发堆叠上下文呢?
- 根元素 (HTML),
- z-index 值不为 "auto"的 绝对/相对定位
- 一个 z-index 值不为 "auto"的 flex 项目 (flex item),即:父元素 display: flex|inline-flex,
- opacity 属性值小于 1 的元素(参考 the specification for opacity),
- transform 属性值不为 "none"的元素,
- mix-blend-mode 属性值不为 "normal"的元素,
- filter值不为“none”的元素,
- perspective值不为“none”的元素,
- isolation 属性被设置为 "isolate"的元素,
- position: fixed
- 在 will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值
- -webkit-overflow-scrolling 属性被设置 "touch"的元素
堆叠上下文的含义以及对z-index产生的影响
什么是堆叠上下文呢?按照mdn的文档:
层叠上下文是HTML元素的三维概念,这些HTML元素在一条假想的相对于面向(电脑屏幕的)视窗或者网页的用户的z轴上延伸,HTML元素依据其自身属性按照优先级顺序占用层叠上下文的空间。
其实堆叠上下文和BFC是一模一样的,BFC可以看作是block-level box的一个固有属性 ;而堆叠上下文可以看作任何元素的一个特殊属性。给一个元素设置上文中的任意一个css属性,就会使此元素触发堆叠上下文。
对z-index的影响就是:在堆叠上下文中,其子元素的 z-index 值只在父级堆叠上下文中有意义。子级堆叠上下文被自动视为父级堆叠上下文的一个独立单元。每个堆叠上下文完全独立于它的兄弟元素:当处理层叠时只考虑子元素。
Note: 层叠上下文的层级是 HTML 元素层级的一个层级,因为只有某些元素才会创建层叠上下文。可以这样说,没有创建自己的层叠上下文的元素 将被父层叠上下文包含。