深入理解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来控制整体的堆叠顺序。这种方法减少了单独管理每个元素所需的图层数量,从而降低了渲染复杂度,提高了性能。

相关推荐
前端李二牛6 小时前
现代CSS属性兼容性问题及解决方案
前端·css
未来之窗软件服务7 小时前
internationalization 全球系统风格分享,新加坡,墨西哥,泰国,印度,越南—仙盟创梦IDE
css·css3·收银系统开发·仙盟创梦ide·东方仙盟·全球化布局
典学长编程9 小时前
前端开发(HTML,CSS,VUE,JS)从入门到精通!第五天(jQuery函数库)
javascript·css·ajax·html·jquery
张元清10 小时前
解密苹果最新 Liquid Glass 效果:如何用代码重现 iOS 设计系统的视觉魔法
前端·css·面试
天下无贼10 小时前
【轮播图】H5端轮播图、横向滑动、划屏效果实现方案——Vue3+CSS position
css·vue.js
Likeyou710 小时前
HTML无尽射击小游戏包含源码,纯HTML+CSS+JS
javascript·css·html
前端Hardy10 小时前
这个你一定要知道,如何使用Pandoc创建HTML网页版文档?
前端·javascript·css
前端老鹰10 小时前
CSS scrollbar-width:轻松定制滚动条宽度的隐藏属性
前端·css
潘小安12 小时前
【译】六个开发高手使用的 css 动画秘诀
前端·css·性能优化
JuneXcy14 小时前
13.Home-面板组件封装
前端·javascript·css