深入理解CSS层叠上下文与z-index🤓👆

层叠上下文

假设页面是三维立体的,那么用户就是正对着观测页面(浏览器),而HTML元素就可以沿着那条虚构的z轴叠加。层叠上下文就是对这些HTML元素的三维构想。而HTML通过特定的属性来占据z轴更上方的位置,以此来确定它们的堆叠顺序。

当然并非所有元素都能形成新的层叠上下文,必须是满足特定条件的元素才可以。(例如:含非autoz-index值)

创建层叠上下文的前提条件:

  • 元素的position属性设置为relativeabsolutefixedsticky
  • 元素使用了某些特定CSS属性,如 opacity 小于 1, transform 不是 none 等。

z-index属性

z-index属性在css中用于控制元素在z轴(即垂直于页面的方向)上的堆叠顺序,而在默认情况下,所有HTML元素位于同一个层叠上下文中,并且z-index属性默认为auto,这样它们均位于默认的切面上(即不参与特定层叠上下文的堆叠顺序)。

不妨来看个具体的例子:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>层叠上下文</title>
    <style>
        .box1 {
            position: absolute;
            top: 20px;
            left: 20px;
            width: 100px;
            height: 100px;
            background-color: red;
            z-index: 1;
        }
        .box2 {
            position: absolute;
            top: 40px;
            left: 40px;
            width: 100px;
            height: 100px;
            background-color: blue;
            z-index: 2;
        }
    </style>
</head>
<body>
    <div class="box1">box1</div>
    <div class="box2">box2</div>
</body>
</html>

由于box2z-index属性值要大于box1的,所以box1box2覆盖了,最终呈现的效果如图

层叠上下文的父子关系:

在对层叠上下文和z-index有所了解后,不妨来看一个比较奇特的样例

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        html {
            padding: 20px;
        }
        div {
            width: 100px;
            height: 100px;
            position: relative;
        }
        .box1 {
            z-index: 2;
        }
        .box2 {
            z-index: 1;
        }
        p {
            opacity: 0.7;
            position: absolute;
            font-size: 20px;
            width: 100px;
            height: 100px;
        }
        .a {
            opacity: 1;
            border: 1px dashed #009;
            background-color:#ddf;
            z-index: 1; 
        }
        .b {
            border: 1px dashed #696;
            background-color: #cfc;
            top: 20px;
            left: 20px;
            z-index: 2;
        }
        .c {
            border: 1px dashed #900;
            background-color: #fdd;
            top: -20px;
            left: 40px;
            z-index: 9;
        }
    </style>
</head>
<body>
    <div class="box1">
        <p class="a">a</p>
        <p class="b">b</p>
    </div>
    <div class="box2">
        <p class="c">c</p>
    </div>
</body>
</html>

最终呈现的样式为:


分析:

body部分

html 复制代码
<div class="box1">
    <p class="a">a</p>
    <p class="b">b</p>
</div>
<div class="box2">
    <p class="c">c</p>
</div>

abbox1的子元素,cbox2的子元素。

css部分

抛开其他样式,我们主要观察这些元素的z-index属性值。

css 复制代码
.box1 ->  z-index: 2;
.box2 ->  z-index: 1;
.a    ->  z-index: 1; // 蓝色
.b    ->  z-index: 2; // 绿色
.c    ->  z-index: 9;// 红色

由于每个元素都被指定了定位属性和z-index值,所以它们都创建了独自的层叠上下文。不妨先将层叠上下文的层级列在下方:

  • html
    • box1
      • a
      • b
    • box2
      • c

先分析兄弟元素box1box2,这俩个元素是位于同一层叠上下文,比较其z-index值大小即可确定box2被渲染在box1的下方。而ab位于box1的子级层叠上下文中,c位于box2的子级层叠上下文中。

但是并非z-index值越大就一定在越上方,因为z-index只体现在自身位于的层叠上下文中,所以即使cz-index值很大,但是也仅仅是在box2的层叠上下文中"称王称霸"。因为其父元素box2不够努力,只能被压在box1下,那么其子元素c也难逃被box1压在身下的命运。

分辨层叠元素的渲染顺序也很简单,可以将它们的z-index值当做编号通过"."来连接起来(就像版本号一样),把子元素当作父元素的小版本。(版本越高越后渲染)

  • html
    • box1 : z-index为 2
      • a : z-index为 2.1
      • b : z-index为 2.2
    • box2 : z-index为 1
      • c : z-index为 1.9

性能问题:过多的z-index

虽然 z-index属性是管理元素重叠的一个强大工具,但过度使用会导致性能下降,因为浏览器必须计算和维护更多的图层。

解决方案:父图层管理子图层

将相关的元素放在同一个父容器内,并通过设置该父容器的z-index来控制整体的堆叠顺序。这种方法减少了单独管理每个元素所需的图层数量,从而降低了渲染复杂度,提高了性能。

相关推荐
干前端2 小时前
Vue3 组件库工程化实战:BEM 命名规范与 useNamespace 深度解析
前端·css
RFCEO2 小时前
前端编程 课程十四、:CSS核心基础2:选择器优先级 + 伪类选择器(解决冲突+交互效果)
前端·css·交互·css选择器优先级判断规则详解·css important使用·css链接伪类lvha顺序·实现悬浮交互效果
小满zs3 小时前
Next.js第二十五章(CSS方案)
开发语言·javascript·css
红色的小鳄鱼3 小时前
Vue 监视属性 (watch) 超全解析:Vue2 Vue3
前端·javascript·css·vue.js·前端框架·html5
Hacker_Z&Q19 小时前
CSS 笔记2 (属性)
前端·css·笔记
CappuccinoRose1 天前
CSS前端布局总指南
前端·css·学习·布局·flex布局·grid布局·float布局
强子感冒了1 天前
CSS基础学习:CSS选择器与优先级规则
前端·css·学习
layman05282 天前
webpack5 css-loader:从基础到原理
前端·css·webpack
半桔2 天前
【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典
前端·css·html
_OP_CHEN2 天前
【前端开发之CSS】(一)初识 CSS:网页化妆术的终极指南,新手也能轻松拿捏页面美化!
前端·css·html·网页开发·样式表·界面美化