结论
元素重叠时的显示先后由层叠顺序决定,从底到顶依次是:background 和 border、z-index 为负的元素、块级元素、浮动元素、内联元素、z-index 为 0 或 auto 的元素、z-index 为正的元素。z-index 只在同一个层叠上下文内部可比。
最后更新:2026-09-17 · 基于 CSS 2.1 视觉格式化模型附录 E 的层叠规则
二、堆叠上下文
1. 堆叠顺序
深入理解CSS中的层叠上下文和层叠顺序
“层叠顺序”英文称作”stacking order”. 表示元素发生层叠时候有着特定的垂直显示顺序,叠顺序规则:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 显 示 器 +-------------------+ <-----+ 装 饰 | background/border| | +----------------------+ | | 负 z-index | +-----+ +-----------------------+ | | div/块 级 元 素 | <---+ 布 局 | | +-----------------------+ +----+ | float浮 动 元 素 | | | +-----------------------+ +--+ |inline/inline-block盒子 | <--+ 内 容 +-+ +------------------------+ | | z-index:0/z-index:auto | +--+ +------------------------+ +-+ 正 z-index | +------------------------+
用 户 眼 睛
|
从用户的眼睛到显示之间堆叠的顺序依次:
- 正z-index
- z-index:0/z-index:auto(position:relative)
- inline/inline-block元素
- float浮动元素
- 块级元素
- 负z-index
- border
- background
1.1 border在background上的例子
当边框的颜色设置透明度时,背景色改变,视觉上边框的颜色也变了,说明border在background上。
1 2 3 4 5 6 7 8 9
| <style> div { border: 10px solid rgba(255,0,0, 0.2); width: 300px; height: 200px; background: green; } </style> <div></div>
|
1.2 说明div块元素在border上的例子
可以看见子div把父div的border覆盖了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <style> .dad { border: 10px solid rgba(255,0,0, 1); width: 300px; height: 200px; background: green; } .son { width: 70px; height: 20px; background: blue; color: black; margin-left: -5px; } </style> <div class="dad"> 父元素 <div class="son"></div> </div>
|
父div中内联元素与字div中内联元素发生堆叠,后面覆盖前面的
下面的例子中,父div中内联元素由于在子div中内联元素的前面,所以被覆盖了, 同级的元素也是后面的覆盖前面的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <style> .dad { border: 10px solid rgba(255,0,0, 1); width: 300px; height: 200px; background: green; color: red; } .son { width: 70px; height: 20px; background: blue; color: black; margin-top: -10px; } .son1 { color: yellow; margin-bottom: -10px; } </style> <div class="dad"> 父元素 <div class="son"> 子元素 </div> <div class="son1 son">子元素</div> 父元素 </div>
|
1.3 说明float浮动元素在div上的例子
在这个例子中,浮动元素覆盖了div元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <style> .dad { border: 10px solid rgba(255,0,0, 1); width: 300px; height: 200px; background: green; text-indent: -10px; } .son { width: 70px; height: 20px; background: yellow; color: black; margin-left: -5px; } .float { width: 50px; height: 50px; background: blue; float: left; } </style> <div class="dad"> 父元素 <div class="float"></div> <div class="son"></div> </div>
|
1.4 说明内联元素在float浮动元素上面的例子
可以看见内联元素在浮动元素的上面。
内联元素也比浮动元素中的内联元素靠前(在前面)。
浮动元素中的内联元素优先级是没有外边的内联元素优先级高。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <style> .dad { border: 10px solid rgba(255,0,0, 1); width: 300px; height: 200px; background: green; text-indent: -20px; } .float { width: 50px; height: 50px; background: blue; float: left; color: red; } </style> <div class="dad"> 父元素 <div class="float">浮动元素</div> </div>
|
1.5 z-index的值大于等于0的元素在内联元素的上面
z-index的值是auto相当于0。
z-index属性只能给position的值是relative、absolute、fixed设置才会生效。
在下面的例子中,z-index的值大于等于0的元素覆盖在内联元素上面。
而z-index的值大的覆盖小的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <style> .dad { border: 10px solid rgba(255,0,0, 1); width: 300px; height: 200px; background: #ccc; } .float { width: 50px; height: 150px; background: blue; float: left; color: red; } .relative { width: 150px; height: 20px;background: yellow; position: relative; margin-top: -10px; } .absolute { width: 50px; height: 60px;background: green; position: absolute; margin-top: -10px; z-index: 1; } .rel {z-index: 1; margin-top: 0;background: white} </style> <div class="dad"> 11 <div class="float"></div> <div class="relative"></div> <div class="absolute"></div> <div class="relative rel"></div> </div>
|
1.6 z-index的值为负数的元素在background的后面
1 2 3 4 5 6 7 8 9 10 11 12 13
| <style> .dad { border: 10px solid red; width: 300px; height: 100px; background: #ccc; } .negative { width: 50px; height: 150px;background: green; position: absolute; z-index: -1; } </style> <div class="dad"> <div class="negative"></div> </div>
|
2. 层叠上下文(堆叠上下文)
mdn层叠上下文介绍
层叠上下文是HTML元素的三维概念,这些HTML元素在一条假想的相对于面向(电脑屏幕的)视窗或者网页的用户的z轴上延伸,HTML元素依据其自身属性按照优先级顺序占用层叠上下文的空间。
满足下面任何一个条件就会触发层叠上下文:
- 根元素 (HTML),
- z-index 值不为 “auto”的 绝对/相对定位,
- position: fixed
- 一个 z-index 值不为 “auto”的 flex 项目 (flex item),即:父元素 display: flex|inline-flex,
- opacity 属性值小于 1 的元素(参考 the specification for opacity),
- transform 属性值不为 “none”的元素,
- mix-blend-mode 属性值不为 “normal”的元素,
- filter值不为“none”的元素,
- perspective值不为“none”的元素,
- isolation 属性被设置为 “isolate”的元素,
- 在 will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值(参考 这篇文章)
- -webkit-overflow-scrolling 属性被设置 “touch”的元素
层叠上下文主要影响z-index的属性。
从上面的条件中可以看见,一个网页会有一个默认的层叠上下文(根元素 HTML),当元素发生堆叠的时候:
- 从元素往上找,找到父辈中触发了层叠上下文的元素,没有就是根元素。
- 两个父辈触发层叠上下文的元素比较堆叠优先级,高的子元素在上面。
- 如果父辈元素堆叠优先级相同,后面的覆盖前面的。
- 如果他们的触发层叠上下文的父辈元素时同一个,那么就按照层叠顺序堆叠。
在下面的例子中:
- 父元素的层叠上下文优先级相同时,那么b1覆盖a1,
- 把a元素的层叠上下文优先级变大,那么b1则在整个a元素下面。
- 如果a元素和b元素同时修改为
z-index:zuto,那么a1元素在b1元素上面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <style> .dad { width: 300px; height: 200px; background: #ccc; } .negative { width: 150px; height: 70px;background: green; position: relative; } .a1,.b1 { width: 100px; height: 20px;background: yellow; position: relative; } .a1 {z-index: 10;} .b1 {background: blue; margin-top: -55px; z-index: 0;} .a { z-index: 2; } .b { z-index: 2; width: 170px; background: white;} </style> <div class="dad"> <div class="negative a">a <div class="a1">a1</div> </div> <div class="negative b">b <div class="b1">b1</div> </div> </div>
|
常见问题
为什么 z-index 设成 9999 还是压不住别的元素
因为 z-index 只在同一个层叠上下文里比较。如果你的元素所在的父级创建了一个新的层叠上下文,而那个父级本身的层级低于目标元素,子元素设多大都跳不出去。要改的是父级的层级,不是子元素的。
哪些属性会创建新的层叠上下文
根元素 html、position 为 relative/absolute 且 z-index 不为 auto、position 为 fixed 或 sticky、opacity 小于 1、transform、filter、will-change 等都会创建。opacity 和 transform 最容易被忽略,因为它们看起来跟层级无关。
z-index 为负的元素会跑到哪里
会跑到常规流的块级元素后面,但仍在所属层叠上下文的 background 和 border 之前。所以给子元素设 z-index: -1 时,它会被父元素的背景遮住而不是显示在下层。