堆叠上下文 与 z-index 的关系
#R1
#bom
目录
1. 什么是堆叠上下文?
堆叠上下文(Stacking Context)是 HTML 元素在渲染时的三维概念化模型,它沿着假想的 z 轴延伸,决定了元素在重叠时的显示顺序。可以将其想象成一个层级系统或容器,其中的内容按照特定规则进行分层和渲染。
2. 堆叠上下文的形成条件
以下情况会创建新的堆叠上下文:
/* 1. 文档根元素 <html> */
/* 2. position 不为 static 且设置了 z-index 值的元素 */
.element {
position: relative;
z-index: 1;
}
/* 3. position 为 fixed 或 sticky 的元素 */
.element {
position: fixed;
}
/* 4. flex 容器的子元素且 z-index 不为 auto */
.flex-child {
z-index: 1;
}
/* 5. grid 容器的子元素且 z-index 不为 auto */
.grid-child {
z-index: 1;
}
/* 6. opacity 值小于 1 的元素 */
.element {
opacity: 0.99;
}
/* 7. transform 不为 none 的元素 */
.element {
transform: scale(1);
}
/* 8. filter 不为 none 的元素 */
.element {
filter: blur(0px);
}
/* 9. perspective 不为 none 的元素 */
.element {
perspective: 1000px;
}
/* 10. isolation 为 isolate 的元素 */
.element {
isolation: isolate;
}
/* 11. will-change 指定了任何属性 */
.element {
will-change: opacity;
}
/* 12. contain 为 layout、paint 的元素 */
.element {
contain: layout;
}
/* 13. backdrop-filter 不为 none 的元素 */
.element {
backdrop-filter: blur(10px);
}
/* 14. mix-blend-mode 不为 normal 的元素 */
.element {
mix-blend-mode: multiply;
}
2.1. 根元素(默认)
- 文档根元素
<html>
自动生成堆叠上下文
2.2. 定位相关
/* 以下条件会创建堆叠上下文 */
.stacking-context {
/* 1. 定位元素 + z-index */
position: relative | absolute | fixed | sticky;
z-index: <number>; /* 不为 auto */
/* 2. 固定定位元素 */
position: fixed;
/* 3. 粘性定位元素 */
position: sticky;
}
2.3. CSS 属性触发
.stacking-context {
/* 透明度 */
opacity: <number>; /* 小于1 */
/* 变换 */
transform: <transform-function>;
/* 滤镜 */
filter: <filter-function>;
/* 混合模式 */
mix-blend-mode: <blend-mode>;
/* 隔离 */
isolation: isolate;
/* 其他 */
perspective: <length>;
clip-path: <clip-source>;
mask: <mask-layer>;
backdrop-filter: <filter-function>;
}
2.4. 新特性触发
.stacking-context {
/* 性能优化属性 */
will-change: opacity, transform;
/* 包含属性 */
contain: layout | paint;
/* 层合成属性 */
perspective: 1000px;
}
3. 堆叠顺序(Stacking Order)
在同一个堆叠上下文内,元素按照以下顺序从后到前堆叠:
- 堆叠上下文的根元素的背景和边框
- z-index 为负值的定位子元素(按照 z-index 值从小到大)
- 常规流中的非定位子元素、块级盒子
- 浮动元素
- 常规流中的内联元素
- z-index 为 auto 或 0 的定位子元素
- z-index 为正值的定位子元素(按照 z-index 值从小到大)
3.1. 示例代码
/* 堆叠顺序示例 */
.stacking-context {
position: relative;
z-index: 0;
}
.negative-z-index {
position: absolute;
z-index: -1;
/* 将显示在背景之上,其他元素之下 */
}
.normal-flow {
/* 非定位元素,按照文档顺序堆叠 */
}
.float {
float: left;
/* 浮动元素在非定位元素之上 */
}
.inline {
display: inline;
/* 内联元素在浮动元素之上 */
}
.zero-z-index {
position: relative;
z-index: 0;
/* 在内联元素之上 */
}
.positive-z-index {
position: absolute;
z-index: 1;
/* 在最上层 */
}
4. 堆叠上下文的特性
4.1. 层级包含性
- 子堆叠上下文被完全包含在父堆叠上下文之内
- 子元素无法穿透父元素的堆叠层级
/* 父元素创建堆叠上下文 */
.parent {
position: relative;
z-index: 1;
}
/* 子元素的 z-index 只在父元素内部比较 */
.child {
position: absolute;
z-index: 999; /* 不会影响父元素外的元素 */
}
4.2. 兄弟关系
/* 两个独立的堆叠上下文 */
.context-1 {
position: relative;
z-index: 1;
}
.context-2 {
position: relative;
z-index: 2;
/* 会在 context-1 之上,无论子元素的 z-index 多大 */
}
5. 实际应用场景
5.1. 模态框(Modal)
.modal-overlay {
position: fixed;
z-index: 100;
background: rgba(0, 0, 0, 0.5);
}
.modal-content {
position: fixed;
z-index: 101;
}
5.2. 下拉菜单
.dropdown {
position: relative;
}
.dropdown-content {
position: absolute;
z-index: 1;
}
5.3. 固定导航栏
.navbar {
position: fixed;
top: 0;
z-index: 1000; /* 确保在其他内容之上 */
}
6. z-index
6.1. 基本概念
z-index 是 CSS 中用于控制元素在 z 轴上堆叠顺序的属性。它决定了元素在重叠时哪个元素显示在上层。
- z-index 只在创建了堆叠上下文的元素中生效
- 堆叠上下文形成独立的层级体系
- 多种 CSS 属性都可能创建新的堆叠上下文
- 合理使用堆叠规则可以创建复杂的层叠效果
取值范围
z-index: auto; /* 默认值 */
z-index: 0; /* 整数值 */
z-index: 999; /* 正整数 */
z-index: -1; /* 负整数 */
z-index: inherit; /* 继承父元素 */
z-index: initial; /* 初始值 */
z-index: unset; /* 未设置 */
7. 其他
7.1. z-index 管理策略:使用变量
/* 使用变量管理 z-index */
:root {
--z-dropdown: 100;
--z-sticky: 200;
--z-fixed: 300;
--z-modal-backdrop: 400;
--z-modal: 500;
--z-popover: 600;
--z-tooltip: 700;
}
.dropdown { z-index: var(--z-dropdown); }
.sticky-header { z-index: var(--z-sticky); }
.fixed-nav { z-index: var(--z-fixed); }
.modal-backdrop { z-index: var(--z-modal-backdrop); }
.modal { z-index: var(--z-modal); }
.popover { z-index: var(--z-popover); }
.tooltip { z-index: var(--z-tooltip); }
7.2. 调试技巧
/* 使用 outline 调试重叠元素 */
* {
outline: 1px solid red;
}
/* 使用不同颜色标识不同堆叠上下文 */
.stacking-context {
background: rgba(255, 0, 0, 0.1);
}
/* 使用不同颜色的轮廓线标识堆叠上下文 */
.debug-stacking {
outline: 2px solid red;
}
/* 临时提升元素层级进行测试 */
.debug-top {
position: relative;
z-index: 999999;
}
7.3. z-index 失效
/* 问题:z-index 不生效 */
.element {
z-index: 999; /* 无效 */
}
/* 解决方案:添加定位属性 */
.element {
position: relative;
z-index: 999; /* 现在生效了 */
}
7.4. 层级穿透
/* 问题:子元素超出父元素层级 */
.parent {
position: relative;
z-index: 1;
}
/* 解决方案:确保父元素 z-index 足够高 */
.parent {
position: relative;
z-index: 1000;
}
7.5. 隔离堆叠上下文
/* 使用 isolation 创建新的堆叠上下文 */
.isolated-context {
isolation: isolate;
}
7.6. 常见问题
- z-index 不生效
- 元素无法置于顶层
- 层级关系混乱
7.7. 最佳实践
/* 使用 CSS 变量管理 z-index */
:root {
--z-dropdown: 100;
--z-modal: 1000;
--z-tooltip: 1500;
--z-notification: 2000;
}
/* 使用语义化的类名和合理的层级值 */
.dropdown { z-index: var(--z-dropdown); }
.modal { z-index: var(--z-modal); }
.tooltip { z-index: var(--z-tooltip); }
.notification { z-index: var(--z-notification); }