📚 层叠上下文
📖 概述
通常情况下,我们会以二维的方式来看待浏览器中的网页,即将网页视为一个平面。但事实是,html中的每个元素都拥有一个三维位置(CSS2.1中指出),除了水平方向的x轴和垂直方向的y轴,还有深度方向的z轴。
若想要彻底理解z轴的方向,我们可以假定用户正面向浏览器视窗中心,而用户视觉与屏幕中心点的连线便是z轴方向。而层叠上下文(Stacking Context)可以看作是一块空间或一个容器,其内部的元素沿z轴按照一定规则进行堆叠。
🏗️ 上下文创建
文档中的层叠上下文由满足以下任一条件的元素产生。
- 文档根元素,即
html
position
值为absolute
(绝对定位)或relative
(相对定位)且其z-index
不为auto
的元素position
值为fixed
(固定定位)或sticky
(粘性定位)的元素- flex容器的子元素,且
z-index
值不为auto
- grid容器的子元素,且
z-index
值不为auto
opacity
属性值小于1
的元素mix-blend-mode
属性值不为normal
的元素isolation
属性值为isolate
的元素。transform
、filter
、backdrop-filter
、perspective
、clip-path
、mask
、mask-image
、mask-border
任意属性值不为none
的元素。
📏 层叠规则
在本文中,层叠指的是什么?层叠也称为堆叠,描述了元素在z轴上的绘制顺序,即一些元素会覆盖在另一些元素之上。
在HTML文档中,根元素(html
)创建了最底层的层叠上下文,被称为根层叠上下文。根层叠上下文之上可以有多个子层叠上下文,这些子层叠上下文又可以拥有自己的子层叠上下文,从而形成了一个层次化的结构。
每个创建层叠上下文的元素都完全独立于它的兄弟元素,且处理层叠时只考虑子元素。那如何处理层叠呢?层叠水平(stacking level)越大的元素就在z轴上越靠前。也就是说,层叠水平高的元素会显示在层叠水平较低的元素之上。而层级水平的高低是由层叠顺序(stacking order)体现的,具体规则如下。
tip:
- 当相邻的两个元素的层叠顺序相同时,那么层叠水平由它们在文档中的出现顺序决定。先出现的元素,其层叠水平较高。
- 在层叠过程中,子层叠上下文可以被视作一个整体在其父层叠上下文中层叠。
z-index
属性控制的层叠只适用定位盒子(position
值为非static
)、flex盒子子元素、grid盒子子元素。
🕵️♀️ 案例
某HTML文档内容如下。
html
<html class="bg-[#539271]">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>层叠上下文案例</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<div id="A" class="opacity-90 bg-[#D9D9D9] w-[300px] h-[200px]">
<div id="B" class="fixed z-[-1] bg-[#C36077] w-[200px] h-[200px] left-0 top-0"></div>
</div>
<div id="C" class="relative z-[2] bg-[#7985EC] w-[200px] h-[200px]"></div>
</body>
</html>
根据分析,可得该文档的层叠上下文的层级结构如下图所示。
试问,在该文档中,若以下两个元素若重叠了,哪个元素会排在上方?
- ①层叠上下文A上的浮动元素、②层叠上下文A上的常规流块元素。
html
<div class="float-left bg-orange-400 w-32 h-32 "></div> <!-- 元素① -->
<div class="block bg-green-400 w-32 h-32 ml-24"></div> <!-- 元素② -->
- ①层叠上下文A上的绝对定位且
z-index
为99的元素、②层叠上下文B的创建元素。
html
<div class="absolute w-32 h-32 bg-cyan-400 z-[99]"></div> <!-- 元素① -->
- ①层叠上下文B的创建元素、②层叠上下文A上的浮动元素。
html
<div class="float-left bg-yellow-300 w-32 h-32"></div> <!-- 元素② -->
①层叠上下文B的创建元素、②层叠上下文C的创建元素。
①层叠上下文B上的相对定位且
z-index
为99的元素、②层叠上下文C上的相对定位且z-index
为-2的元素。
html
<div class="bg-indigo-900 w-32 h-32 relative z-[99]"></div> <!-- 元素① -->
<div class="bg-purple-500 w-32 h-32 relative z-[-2] -top-40"></div> <!-- 元素② -->