CSS基础教程

 主页   资讯   文章   代码   电子书 

z-index和栈空间

本节内容,将深入研究z-index这个属性和栈空间(stacking context)。

一.z-index

MDN上是这样描述z-index的:

z-index属性设定了一个定位元素及其后代元素或flex项目的z-order。 当元素之间重叠的时候,z-index较大的元素会覆盖较小的元素在上层进行显示。

MDN中还提到了下面两点内容,作为补充。

1.盒子在当前堆叠上下文中的堆叠层级。

2.盒子是否创建一个本地堆叠上下文。

如果你足够细心,应该能够注意到堆叠上下文这个词。本着好好学习天天向上的精神,我们来个追查到底。

先来看一个例子。

为什么z-index设置为-1,但是它还是在最上面显示呢?

其实罪魁祸首就是堆叠上下文

二.栈空间

栈空间(stacking context),也称堆叠上下文w3c中有详细介绍,我在这里就扮演一个搬运工的角色,将这部分内容搬出来。

在css(html)的世界中,所有的元素都是处于三维世界中的,对的是三维的,它们不仅仅只有x和y坐标,还有一个z坐标,在图形学中z坐标也叫做深度。你可以认为这个css的坐标系的x正轴方向是从左到右,y正轴方向是从上到下,z轴方向是从屏幕里指向屏幕外的。

每个元素box都属于一个栈空间,这些元素box在栈空间内都有一个整数的栈层级,元素的栈层级可以用z-index,默认栈层级为0,同一个栈空间内,栈层级大的元素永远在栈层级小的元素的前面,栈层级大表示其z坐标大,越靠近屏幕外面,离人眼越近,所以一般我们可以通过设置z-index使某个元素显示在其他元素的上面。

stacking context

栈空间的创建

根元素会创建一个根栈空间(root stacking context),根栈空间内的元素有可能会创建一个局部的栈空间,然后局部栈空间内的元素可能又会创建一个局部栈空间内的局部栈空间...

创建局部栈空间的元素有两个栈层级:一个是它在它所属的栈空间中的栈层级(栈层级由它的z-index设置),另一个是它在自己所创建的局部栈空间内的栈层级(栈层级为0)。

子元素的栈层级与它的父元素的栈层级相等,除非设置它的z-index属性为一个不同的值。

1.position属性

如果设置了一个元素的position属性,那么该元素有可能会创建一个局部栈空间。具体由该元素的z-index属性确定。

z-index有两个作用:

  1. 设置元素在所属栈空间内的栈层级。
  2. 决定元素是否创建了一个局部栈空间。

z-index接受两种值:关键字auto、整数。

  1. z-index:auto;: 元素在所属栈空间内的栈层级为0,元素不会创建新的栈空间(局部栈空间),除非该元素是页面根元素,页面根元素默认会创建一个栈空间。
  2. z-index:<interger>: 元素在所属栈空间内的栈层级为0,设置的<interger>,元素会创建一个新的局部栈空间。

所以前面那个例子,我们设置了z-index:-1;没有效果,因为<span>元素处于新的局部栈空间内。而它的父元素在外层栈空间内的栈层级为0。

2.其他

还有许多其他情况也可以创建新的栈空间,这里我做一个总结。

  • 文档根元素(html)。
  • positionabsoluterelative的元素,并且z-index不为auto的元素。
  • positionfixed或者sticky的元素。
  • flex容器的子元素(项目),且z-index值不为auto
  • grid容器的子元素(项目),且z-index值不为auto
  • opacity属性值小于1的元素
  • mix-blend-mode属性值不为normal的元素;
  • 以下任意属性值不为 none 的元素:
    • transform
    • filter
    • perspective
    • clip-path
    • mask/mask-image/mask-border
  • isolation属性值为isolate的元素。
  • -webkit-overflow-scrolling属性值为touch的元素。

三.绘制顺序

元素的绘制顺序,影响了当两个元素重叠时,其中一个元素是否会被另一个元素遮住。

在一个栈空间内,绘制顺序从先往后大致如下。

  1. 构成该栈空间元素的背景和边框(先绘制背景,再绘制边框)。
  2. z-index为负值的并且创建了局部栈空间的元素,z-index最小的先绘制。
  3. 处在正常文档流内,position为static的非内联(non-inline)元素。
  4. position为static的浮动元素。
  5. 处在正常文档流内,position为static的内联(inline)元素,包括内联table和内联块(inline blocks)。
  6. z-index为0的并且创建了局部栈空间的元素和z-index为0并且position为非static的元素。
  7. z-index为正值的并且创建了局部栈空间的元素,z-index最小的先绘制。

更详细的绘制顺序可以参考这里

(完)