Skip to content

📚 层叠上下文

思维导图-层叠上下文

📖 概述

​ 通常情况下,我们会以二维的方式来看待浏览器中的网页,即将网页视为一个平面。但事实是,html中的每个元素都拥有一个三维位置(CSS2.1中指出),除了水平方向的x轴和垂直方向的y轴,还有深度方向的z轴。

浏览器坐标系

​ 若想要彻底理解z轴的方向,我们可以假定用户正面向浏览器视窗中心,而用户视觉与屏幕中心点的连线便是z轴方向。而层叠上下文(Stacking Context)可以看作是一块空间或一个容器,其内部的元素沿z轴按照一定规则进行堆叠。

层叠视觉效果

🏗️ 上下文创建

​ 文档中的层叠上下文由满足以下任一条件的元素产生。

  1. 文档根元素,即html
  2. position值为absolute(绝对定位)或relative(相对定位)且其z-index不为auto的元素
  3. position值为fixed(固定定位)或sticky(粘性定位)的元素
  4. flex容器的子元素,且z-index值不为auto
  5. grid容器的子元素,且z-index值不为auto
  6. opacity属性值小于1的元素
  7. mix-blend-mode属性值不为normal的元素
  8. isolation属性值为isolate的元素。
  9. transformfilterbackdrop-filterperspectiveclip-pathmaskmask-imagemask-border任意属性值不为none的元素。

📏 层叠规则

​ 在本文中,层叠指的是什么?层叠也称为堆叠,描述了元素在z轴上的绘制顺序,即一些元素会覆盖在另一些元素之上。

​ 在HTML文档中,根元素(html)创建了最底层的层叠上下文,被称为根层叠上下文。根层叠上下文之上可以有多个子层叠上下文,这些子层叠上下文又可以拥有自己的子层叠上下文,从而形成了一个层次化的结构。

​ 每个创建层叠上下文的元素都完全独立于它的兄弟元素,且处理层叠时只考虑子元素。那如何处理层叠呢?层叠水平(stacking level)越大的元素就在z轴上越靠前。也就是说,层叠水平高的元素会显示在层叠水平较低的元素之上。而层级水平的高低是由层叠顺序(stacking order)体现的,具体规则如下。

层叠顺序

tip:

  1. 当相邻的两个元素的层叠顺序相同时,那么层叠水平由它们在文档中的出现顺序决定。先出现的元素,其层叠水平较高。
  2. 在层叠过程中,子层叠上下文可以被视作一个整体在其父层叠上下文中层叠。
  3. 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>

​ 根据分析,可得该文档的层叠上下文的层级结构如下图所示。

示例

​ 试问,在该文档中,若以下两个元素若重叠了,哪个元素会排在上方?

  1. ①层叠上下文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> <!-- 元素② -->
  1. ①层叠上下文A上的绝对定位且z-index为99的元素、②层叠上下文B的创建元素。
html
<div class="absolute w-32 h-32 bg-cyan-400 z-[99]"></div> <!-- 元素① -->
  1. ①层叠上下文B的创建元素、②层叠上下文A上的浮动元素。
html
<div class="float-left bg-yellow-300 w-32 h-32"></div> <!-- 元素② -->
  1. ①层叠上下文B的创建元素、②层叠上下文C的创建元素。

  2. ①层叠上下文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> <!-- 元素② -->

上次更新于: