首页 / CSS 入门教程 / 层级 z-index

CSS 入门教程

层级 z-index

本教程共 44 篇 · 第 27 篇 · 更新于 2026-07-29 · 约 8 分钟阅读

z-index层级层叠上下文stacking context堆叠顺序

27. 层级 z-index

本节目标:理解 z-index 的作用原理,掌握层叠上下文的创建方式,解决元素层级覆盖问题。

z-index 基本用法

z-index 控制定位元素的堆叠顺序。值越大,元素越靠上。

/* 背景层 */
.background {
    position: absolute;
    z-index: 1;
}

/* 中间层 */
.middle {
    position: absolute;
    z-index: 2;
}

/* 最上层 */
.foreground {
    position: absolute;
    z-index: 3;
}
<div class="container">
    <div class="background">背景</div>
    <div class="middle">中间</div>
    <div class="foreground">前景</div>
</div>

z-index 只对定位元素生效(position 不为 static)。普通流式元素设置 z-index 无效。

z-index 的值

效果
auto默认值,继承父级层级,不创建新层叠上下文
数字正整数或负整数,数值越大越靠上
负数放到父级背景后面,可做背景效果
/* 负值 z-index 做背景 */
.behind-text {
    position: absolute;
    z-index: -1;      /* 放到文字后面 */
    top: 0;
    left: 0;
}

负值 z-index 常用于在文字后面放置装饰性图片或背景图案。

没有 z-index 时的默认规则

如果多个定位元素重叠且都没设 z-index,后出现的 HTML 元素在上面。

<div class="box1">第一个</div>  <!-- 在下面 -->
<div class="box2">第二个</div>  <!-- 在上面 -->
.box1, .box2 {
    position: absolute;
    width: 100px;
    height: 100px;
}

box2 会盖住 box1,因为它在 HTML 中后出现。

层叠上下文(Stacking Context)

z-index 不是全局比较的。每个层叠上下文是一个独立的小世界,内部的 z-index 只在该世界内有效。

/* 父元素创建层叠上下文 */
.parent-a {
    position: relative;
    z-index: 10;
}

.parent-b {
    position: relative;
    z-index: 1;       /* 比 parent-a 小 */
}

/* parent-b 的子元素 */
.parent-b .child {
    position: absolute;
    z-index: 9999;    /* 再大也超不出 parent-b 的范围 */
}

效果:尽管 child 的 z-index 是 9999,但它仍在 parent-a 的下面,因为 parent-b 整体层级低于 parent-a。

理解层叠上下文是掌握 z-index 的关键。子元素的层级受限于父级层叠上下文。

创建层叠上下文的条件

以下情况会自动创建层叠上下文:

  1. 根元素 <html> 本身就是层叠上下文
  2. position + z-index:定位元素且 z-index 不为 auto
  3. opacity < 1:透明度小于 1
  4. transform:不为 none
  5. filter:不为 none
  6. will-change:指定了 transform 或 opacity
  7. isolation: isolate:显式创建
/* 以下都会创建层叠上下文 */
.example1 { opacity: 0.99; }
.example2 { transform: scale(1); }
.example3 { filter: blur(0); }
.example4 { isolation: isolate; }

层叠顺序规则

同一个层叠上下文内,元素的堆叠顺序从下到上:

  1. 层叠上下文的背景和边框
  2. 负 z-index 的子元素
  3. 块级元素(正常流)
  4. 浮动元素
  5. 行内元素
  6. z-index: auto 或 0 的定位元素
  7. 正 z-index 的子元素
/* 层叠顺序示例 */
.box {
    position: relative;
}

.box .background {
    position: absolute;
    z-index: -1;     /* 第2层:负z-index */
}

.box .content {
    /* 无 z-index,按文档流排列 */
}

.box .overlay {
    position: absolute;
    z-index: 1;      /* 第7层:正z-index */
}

常见层级问题排查

问题一:z-index 不生效

/* 错误:元素没有定位 */
.overlay {
    z-index: 999;           /* 无效! */
}

/* 正确:先设定位 */
.overlay {
    position: absolute;     /* 或 relative、fixed */
    z-index: 999;
}

问题二:z-index 设了很大值还是被盖住

原因:父元素的层叠上下文层级太低。

/* 排查思路 */
.parent {
    position: relative;
    z-index: 1;           /* 父级只有 1 */
}

.child {
    position: absolute;
    z-index: 9999;        /* 再大也没用,出不了父级的层 */
}

解决办法:提高父级 z-index,或者把子元素移到更高层级的父级下。

问题三:opacity 影响层级

/* opacity 会创建层叠上下文 */
.card {
    opacity: 0.99;        /* 意外创建层叠上下文 */
    z-index: 1;
}

/* 可能影响其他定位元素的层级关系 */

实战:弹窗层级管理

/* 遮罩层 */
.overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 100;
}

/* 弹窗 */
.modal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: white;
    padding: 20px;
    z-index: 101;          /* 比遮罩层高 */
}

/* 弹窗内的关闭按钮 */
.modal .close {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 1;            /* 弹窗内部层级 */
}

管理大型项目的层级,建议用 CSS 变量统一管理 z-index 值,避免到处写魔法数字。

:root {
    --z-dropdown: 100;
    --z-sticky: 200;
    --z-overlay: 300;
    --z-modal: 400;
    --z-toast: 500;
}

.dropdown { z-index: var(--z-dropdown); }
.sticky { z-index: var(--z-sticky); }
.overlay { z-index: var(--z-overlay); }
.modal { z-index: var(--z-modal); }
.toast { z-index: var(--z-toast); }

这样层级关系一目了然,维护起来也方便。

小结

  • z-index 只对定位元素(position 不为 static)生效
  • z-index 值越大越靠上,负值放到父级背景后面
  • 层叠上下文是独立的小世界,内部 z-index 只在该范围内有效
  • opacity < 1、transform、filter 等会创建层叠上下文
  • 子元素层级受限于父级层叠上下文,再大也超不出父级范围
  • 大型项目建议用 CSS 变量统一管理 z-index 值