Skip to content
字数
1954 字
阅读时间
8 分钟

概述

在 CSS2.1 规范中,每个盒模型的位置是三维的,分别是平面画布上的 x 轴,y 轴以及表示层叠的 z 轴。

层叠上下文即元素在某个层级上 z 轴方向的排列关系。

其中包含几个重要的概念:层叠上下文(Stacking Context)、层叠等级(Stacking Level,也叫层叠水平)、层叠顺序(Stacking Order)、z-index

层叠上下文

层叠上下文是一个抽象性的概念,类似 BFC ,具象化理解就是,网页中的元素大多是普通元素,而一旦普通元素拥有了层叠上下文就能变成 层叠上下文元素 ,能够覆盖在普通元素上方进行显示

层叠上下文 1 (Stacking Context 1) 是由文档根元素形成的, 层叠上下文 2 和 3 (Stacking Context 2, 3) 都是层叠上下文 1 (Stacking Context 1) 上的层叠层。 他们各自也都形成了新的层叠上下文,其中包含着新的层叠层。

形成条件

  • 文档根元素(< html >);
  • position 值为 absolute(绝对定位)或 relative(相对定位)且 z-index 值不为 auto 的元素;
  • position 值为 fixed(固定定位)或 sticky(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持);
  • flex (flex) 容器的子元素,且 z-index 值不为 auto;
  • grid (grid) 容器的子元素,且 z-index 值不为 auto;
  • opacity 属性值小于 1 的元素(参见 the specification for opacity);
  • mix-blend-mode 属性值不为 normal 的元素;
  • 以下任意属性值不为 none 的元素:
    • transform
    • filter
    • backdrop-filter
    • perspective
    • clip-path
    • mask / mask-image / mask-border
  • isolation 属性值为 isolate 的元素;
  • will-change 值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素(参考这篇文章);
  • contain 属性值为 layout、paint 或包含它们其中之一的合成值(比如 contain: strict、contain: content)的元素。

详情参考 MDN:层叠上下文 - CSS(层叠样式表) | MDN

特性

层叠上下文元素有如下特性:

  • 层叠上下文的层叠水平要比普通元素高;
  • 层叠上下文可以阻断元素的混合模式;
  • 层叠上下文可以嵌套,内部层叠上下文及其所有子元素均受制于外部的层叠上下文。
  • 每个层叠上下文和兄弟元素独立,也就是当进行层叠变化或渲染的时候,只需要考虑后代元素。
  • 每个层叠上下文是自成体系的,当元素发生层叠的时候,整个元素被认为是在父层叠上下文的层叠顺序中。

层叠等级

层叠等级 (层叠水平, Stacking Level) 表示同一个层叠上下文中元素在 z 轴上的显示顺序的概念;

所有的元素都有层叠水平,包括层叠上下文元素,层叠上下文元素的层叠水平可以理解为官员的职级,1 品 2 品,县长省长之类

  • 普通元素的层叠等级优先由其所在的层叠上下文决定
  • 层叠等级的比较只有在同一个层叠上下文元素中才有意义
  • 在同一个层叠上下文中,层叠等级描述定义的是该层叠上下文中的元素在 Z 轴上的上下顺序

注意,层叠等级并不一定由 z-index 决定,只有定位元素的层叠等级才由 z-index 决定,其他类型元素的层叠等级由层叠顺序、他们在 HTML 中出现的顺序、他们的父级以上元素的层叠等级一同决定,详细的规则见下面层叠顺序的介绍

z-index

在 CSS 2.1 中, 所有的盒模型元素都处于三维坐标系中。 除了我们常用的横坐标和纵坐标, 盒模型元素还可以沿着 "z 轴 " 层叠摆放, 当他们相互覆盖时, z 轴顺序就变得十分重要。

z-index 只适用于定位的元素,对非定位元素无效,它可以被设置为正整数、负整数、0、auto,如果一个定位元素没有设置 z-index,那么默认为 auto;

元素的 z-index 值只在同一个层叠上下文中有意义。如果父级层叠上下文的层叠等级低于另一个层叠上下文的,那么它 z-index 设的再高也没用。所以如果你遇到 z-index 值设了很大,但是不起作用的话,就去看看它的父级层叠上下文是否被其他层叠上下文盖住了。

层叠顺序

层叠上下文和层叠等级是概念,而层叠顺序是规则,是元素排列遵循的一系列方式

css3 后的改进版:

不过上面图示的说法有一些不准确,按照 W3 官方 的说法,准确的 7 层为:

  1. the background and borders of the element forming the stacking context.
  2. the child stacking contexts with negative stack levels (most negative first).
  3. the in-flow, non-inline-level, non-positioned descendants.
  4. the non-positioned floats.
  5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
  6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
  7. the child stacking contexts with positive stack levels (least positive first).

稍微翻译一下:

  1. 形成堆叠上下文环境的元素的背景与边框
  2. 拥有负 z-index 的子堆叠上下文元素 (负的越高越堆叠层级越低)
  3. 正常流式布局,非 inline-block,无 position 定位(static 除外)的子元素
  4. 无 position 定位(static 除外)的 float 浮动元素
  5. 正常流式布局, inline-block 元素,无 position 定位(static 除外)的子元素(包括 display:table 和 display:inline )
  6. 拥有 z-index:0 的子堆叠上下文元素
  7. 拥有正 z-index: 的子堆叠上下文元素(正的越低越堆叠层级越低)

层叠先后判断方法

当元素发生层叠的时候,其覆盖关系遵循下面 2 个准则:

  1. 谁大谁上:当具有明显的层叠水平标示的时候,如识别的 z-indx 值,在同一个层叠上下文领域,层叠水平值大的那一个覆盖小的那一个。通俗讲就是官大的压死官小的。
  2. 后来居上:当元素的层叠水平一致、层叠顺序相同的时候,在 DOM 流中处于后面的元素会覆盖前面的元素。

示例

html
<div class="container container2">
	<div class="inline-block">#divA inline-block</div>
	<div class="float"> #divB float:left</div>
</div>

<div class="container container2">
	<div class="inline-block" style="opacity: 0.9;">#divA inline-block</div>
	<div class="float" style="opacity: 0.9;"> #divB float:left</div>
	
</div>
css
.container{
	position:relative;
	background:#ddd;
	margin-top:10px;
}

.container > div{
	width:200px;
	height:200px;
	line-height:200px;
	color:#333;
	text-align:center;
	font-size:18px;
	font-weight:bold;
	border:1px dashed #e6e6e6;
}

.float{
	float:left;
	background-color:deeppink;
}
.inline-block{
	display:inline-block;
	background-color:yellowgreen;
	margin-left:-100px;
}

显示效果:

上方的 div 是因为 inline-block 的层叠顺序在 float 上,下方的 div 因为 opacity 的设置,导致两个子 div 形成了 层叠上下文,然后二者的层叠水平一致时 DOM 流后面的元素会覆盖前面的

参考

什么是层叠上下文?如何形层叠上下文?层叠顺序是怎样的?

层叠上下文 - CSS(层叠样式表) | MDN

深入理解CSS中的层叠上下文和层叠顺序 « 张鑫旭

贡献者

The avatar of contributor named as jiechen jiechen

页面历史

撰写