堆叠上下文

什么是stacking contexts 堆叠上下文

堆叠上下文是css里一个概念,某些元素可以产生一个堆叠上下文,来包含这个元素的子元素的层级关系。堆叠上下文有两种,一种为根堆叠上下文(root stacking context),一种为局部堆叠上下文(local stacking context)

  • root stacking context
    根堆叠上下文,即HTML根元素默认产生一个stacking context,是html元素,而不是body元素。
  • local stacking context
    菊部堆叠上下文,除了HTML元素,符合以下条件的元素也可生成local stacking context,常见的如下:
  1. positioned(absolute和relative)元素且该元素带有非auto值的z-index属性
  2. 含opacity属性且不为1的元素
  3. 含transform属性且不为auto值的元素
  4. 含filter属性且不为none值得元素
  5. 不常见的

堆叠上下文有什么用

我们在比较不同层的高低是基于堆叠上下文来比较的。

  • 一种情况是某一个元素产生了堆叠上下文,我们就说它的子元素处在同一个堆叠上下文中,我们对这些子元素(即兄弟元素)的层次进行比较
  • 另一种情况是我们要比较的元素不在同一个堆叠上下文中,即他们不在同一个产生堆叠上下文的父元素下(即非兄弟元素)
  • 再来一种,即子元素和父元素的层次比较

第一种情况下层次的堆叠规则如下(从低到高):

  1. 堆叠级别为负值的positioned元素,典型的如z-index=-1
  2. 非positioned元素
  3. positioned且z-index为auto的元素
  4. positioned且z-index为正值的元素,典型的如z-index=1

第二种情况:
1,当比较的两元素处在不同的堆叠上下文时,父元素层次较高(A)的所有子元素(aa),层次上都高于父元素层次低(B)的所有子元素(bb),即子元素不处于同一个堆叠上下文的要依据他们父元素的层次。所以z-index大的元素不一定比z-index小的元素层次高,还要看他们是否处于同一个堆叠上下文中,否时谁所处的堆叠层次高

第三种情况:

  1. 产生堆叠上下文元素的所有子元素都在父元素的上面,无论子元素层次有多低
  2. 当父元素没有产生堆叠上下文时,子元素如果为positioned元素且z-index为负值,就遵循第一情况中所说的,在父元素下面了
  3. 根元素的背景和border处于最低层次中。

含z-index属性定位元素的堆叠规则

以一张图作为开始:
z-index的堆叠规则

  • positioned且设置z-index的元素产生一个堆叠上下文,其子元素将处于父元素创建的这个局部堆叠上下文中。
  • div1,2,3互为兄弟元素,且都设置了position与z-index,故同处在根元素下(根元素默认产生堆叠上下文)产生的这个堆叠上下文中。同理div4,5,6这几个兄弟元素也处在共同的父元素div3的这个堆叠上下文中。两个”这个”是说明这两个堆叠上下文是独立的,是不同的堆叠上下文。
  • 同一个堆叠上下文中,z-index越大,在三维空间上的z轴值越大,层次上表现为在上层。所以div1,2,3在父元素根元素的堆叠上下文中按z-index值大小确定层次关系,div4,5,6在父元素div3的堆叠上下文中按z-index值大小确定层次关系。
  • 不在同一个堆叠上下文,即不属于兄弟关系的元素在比较层次关系时,堆叠规则取决于父元素,div1,2,3处于同一个堆叠上下文中,div3在其同辈元素中高于div2,低于div1。所以div3的子元素div4,5,6与div1,2比较时和父元素保持一致,也都高于div2,低于div1。
  • 子元素与父元素不在同一个堆叠上下文中且层次高于父元素,所以看到div4,5,6都在div3之上。
  • 以上所有元素(除了根元素)都设置了positioned和z-index。

无z-index属性情况下默认的堆叠规则

从下往上的层次关系一次为:

  1. 根元素的背景和border
  2. 普通流中的后代元素,按在html出现的先后顺序
  3. 定位的后代元素或浮动元素,按在html中出现的先后顺序

理论完毕,以下为带图的各种资源,对比理论更容易理解

  1. 层级树
  2. 无z-index情况下的堆叠规则
  3. 浮动情况的堆叠规则,规则貌似和例子实际情况不太一样
  4. 示例