层叠上下文
层叠顺序
说到层叠上下文要先引出一个层叠顺序的概念。CSS中所有的元素默认有以下的层叠顺序,如果是兄弟元素的话,默认后面的覆盖在前面的元素的上面。
- z-index: -
- background
- border
- 块级元素
- 浮动元素
- 内联元素
- z-index: 0
- z-index: +
什么是层叠上下文?
层叠上下文,又叫堆叠上下文,英文名:The stacking context
层叠上下文是HTML元素的三维概念,这些HTML元素在一条假想的相对于面向视窗或者网页的用户的z轴上延伸,HTML元素依据其自身属性按照优先级顺序占用层叠上下文的空间。
听起来很繁琐,那么如何去理解层叠上下文呢?
先看个例子
在html中,有两个块元素dad1
和dad2
,里面分别对应有自己的子元素son1
和son2
。给所有的元素分别设定不同的background-color
以示区分。
然后将dad2
中的子元素向上平移直到与dad1
中的子元素重合,我们会发现,son1
覆盖在了son2
的上面。这是因为我们给son1
设定了z-index
使他高于son2
,一切都很正常。那么是否这个son1
永远都高于son2
呢?
紧接着,我们将两个父元素都加上z-index
为1,那么理论上是不影响刚才的结果变化的,那么神奇的事情发生了...
之前权重较低的son2
突然覆盖在了上面,这是怎么回事呢?
在CSS中,根据正常的层叠顺序,由于有z-index:2
的存在,son2
在页面中的层叠顺序应该高于son1
,但这是相对一个相同的层叠上下文下是生效的。由于在没有给父元素都加上z-index
之前,默认的层叠上下文是整个html
下,页面中的所有元素都在这层叠上下文下,遵守着层叠顺序。当我们给父元素都加上z-index
之后,原来的dad1
和dad2
分别生成了两个新的层叠上下文,其中dad2
的层叠顺序是高于dad1
。那么其中的子元素因为隶属于不同的层叠上下文,要先比较父元素的层叠顺序。就好比在两个不同的部门下,如果部门的等级高,那么这个部门所有人的等级都要高,哪怕是部门中最低的那个,都要高于低级部门的任何一个人。所以son2
会出现在上方,权重比son2
要高。
满足一下任意一个条件,会形成一个层叠上下文:
- 根元素 (HTML),
- z-index 值不为 "auto"的 绝对/相对定位,
- 一个
z-index
值不为auto
的 flex 项目 (flex item) -
opacity
属性值小于 1 的元素 -
transform
属性值不为none
的元素, -
mix-blend-mode
属性值不为normal
的元素, -
filter
值不为none
的元素, -
perspective
值不为none
的元素, -
isolation
属性被设置为isolate
的元素, position: fixed
- 在
will-change
中指定了任意 CSS 属性,即便你没有直接指定这些属性的值 -
-webkit-overflow-scrolling
属性被设置touch
的元素
总结一下,在CSS中,如果没有生成新的层叠上下文,则按照css的默认层叠顺序进行排序。而如果有了新的层叠上下文,则要根据元素所在层叠上下文的权重来排序,层叠上下文高的内部元素,权重都要高于层叠上下文低的内部元素。只要记熟了层叠顺序,理解了层叠上下文的含义,多加练习就可以掌握了。