# CSS的上下文之层叠上下文
看到层叠,大家一定会联想到定位元素会是的元素之间发生“遮挡”,而z-index可以改变他们之间的遮挡优先级,但这仅仅是层叠这一概念中很小的一部分。 本文就来聊一聊css中的层叠上下文到底是如何给元素规定叠加顺序的。
# 一、什么是层叠上下文?
层叠上下文,英文称作”stacking context”. 我们假定用户正面向(浏览器)视窗或网页,而 HTML 元素沿着其相对于用户的一条虚构的 z 轴排开,层叠上下文就是对这些 HTML 元素的一个三维构想。众 HTML 元素基于其元素属性按照优先级顺序占据这个空间。
我们可以把层叠上下文同样可以理解成是元素的属性。
下列方式会形成层叠上下文(列举常见的方式):
- position 值为 static 以外的值,且 z-index 值不为 auto;
- flex (flexbox) 容器的子元素,且 z-index 值不为 auto;
- grid (grid) 容器的子元素,且 z-index 值不为 auto;
- opacity 属性值小于 1 的元素;
- transform属性 不为none的元素;
总结:
在层叠上下文中,子元素同样也按照上面解释的规则进行层叠。 重要的是,其子级层叠上下文的 z-index 值只在父级中才有意义。子级层叠上下文被自动视为父级层叠上下文的一个独立单元。
# 二、什么是层叠水平?
“层叠水平”,英文称作”stacking level”,决定了同一个层叠上下文中元素在z轴上的显示顺序。网页中的每个元素都是独立的个体,他们一定是会有一个类似的排名排序的情况存在。而这个排名排序、论资排辈就是我们这里所说的“层叠水平”。
但注意,每一个层叠上下文内部的子元素都不会突破包裹它的上下文。
下面是引自张鑫旭大大的一段解释,我觉得很通俗易懂:
所有的元素都有层叠水平,包括层叠上下文元素,层叠上下文元素的层叠水平可以理解为官员的职级,1品2品,县长省长之类。然后,对于普通元素的层叠水平,我们的探讨仅仅局限在当前层叠上下文元素中。为什么呢?因为否则没有意义。
翻译成术语就是:普通元素的层叠水平优先由层叠上下文决定,因此,层叠水平的比较只有在当前层叠上下文元素中才有意义。
举例:
大家看下面的一段代码:
现象:
在这个例子中,每个被定位的元素都创建了独自的层叠上下文,因为他们被指定了定位属性和 z-index 值。我们把层叠上下文的层级列在下面:
- DIV #1
- DIV #2
- DIV #3
- DIV #4
- DIV #5
不同层的z-index他们的意义只相对于同一个层叠上下文。你会发现z-index:100的也没有覆盖z-index:1的。
结论:
千万不要把层叠水平和CSS的z-index属性混为一谈。没错,某些情况下z-index确实可以影响层叠水平,但是,只限于定位元素以及flex盒子的孩子元素;而层叠水平所有的元素都存在。
# 三、什么是层叠顺序?
“层叠顺序”英文称作”stacking order”. 表示元素发生层叠时候有着特定的垂直显示顺序,注意,这里跟上面两个不一样,上面的层叠上下文和层叠水平是概念,而这里的层叠顺序是规则。
在CSS2.1的年代,在CSS3还没有出现的时候(注意这里的前提),层叠顺序规则遵循下面这张图(同样是引自张大大的旧图):
# 四、层叠上下文的特性
# 4.1 准则
- 谁大谁上:当具有明显的层叠水平标示的时候,如识别的z-indx值,在同一个层叠上下文领域,层叠水平值大的那一个覆盖小的那一个。通俗讲就是官大的压死官小的。
- 后来居上:当元素的层叠水平一致、层叠顺序相同的时候,在DOM流中处于后面的元素会覆盖前面的元素。 在CSS和HTML领域,只要元素发生了重叠,都离不开上面这两个黄金准则。因为后面会有多个实例说明,这里就到此为止。
# 4.2 特性
- 层叠上下文的层叠水平要比普通元素高;
- 层叠上下文可以嵌套,内部层叠上下文及其所有子元素均受制于外部的层叠上下文。
- 每个层叠上下文和兄弟元素独立,也就是当进行层叠变化或渲染的时候,只需要考虑后代元素。
- 每个层叠上下文是自成体系的,当元素发生层叠的时候,整个元素被认为是在父层叠上下文的层叠顺序中。
讲到这里我们对层叠上下文应该有了一定理解,我们共勉~
# 写在最后
参考:
《CSS基础系列》第五篇文章,下期预告《CSS基础:flex基本属性》
如果对你有所帮助不妨给本项目的github 点个 star (opens new window),这是对我最大的鼓励!
关于我
- 花名:余光
- WX:j565017805
- 沉迷 JS,水平有限,虚心学习中
其他沉淀