理解CSS的 z-index属性
通常情况下,HTML页面可以被认为是二维的,因为文本,图像和其他元素被排列在页面上而不重叠。在这种情况下,只有一个渲染进程,所有元素都知道其他元素所占用的空间。 z-index属性可让你在渲染内容时调整对象分层的顺序。
在 CSS 2.1 中, 所有的盒模型元素都处于三维坐标系中。 除了我们常用的横坐标和纵坐标, 盒模型元素还可以沿着“z 轴”层叠摆放, 当他们相互覆盖时, z 轴顺序就变得十分重要。
这意味着其实 CSS 允许你在现有的渲染引擎上层叠的摆放盒模型元素。 所有的层都可以用一个整数( z 轴顺序)来表明当前层在 z 轴的位置。 数字越大,元素越接近观察者。Z 轴顺序用 CSS 的 z-index 属性来指定。
使用 z-index 很简单: 给它指定一个整数值即可。 然而,在层叠比较复杂的 HTML 元素上使用 z-index 时,结果可能让人觉得困惑,甚至不可思议。 这是由复杂的元素排布规则导致的。 更多细节请参见 CSS-2.1 层叠顺序
1.层叠上下文
层叠上下文是HTML元素的三维概念,这些HTML元素在一条假想的相对于面向(电脑屏幕的)视窗或者网页的用户的z轴上延伸,HTML元素依据其自身属性按照优先级顺序占用层叠上下文的空间。
在之前的增加 z-index 的例子中, 某些 DIV 的渲染顺序是由 z-index 的值影响的。这是因为这些 DIV 具有使他们形成一个层叠上下文的特殊属性。
文档中的层叠上下文由满足以下任意一个条件的元素形成:
1.根元素 (HTML)。
2.z-index 值不为 "auto"的绝对/相对定位。
3.一个 z-index 值不为 "auto"的 flex 项目 (flex item),即:父元素 display: flex|inline-flex。
4.opacity 属性值小于 1 的元素(参考 the specification for opacity)。
5.transform 属性值不为 "none"的元素。
6.mix-blend-mode 属性值不为 "normal"的元素。
7.filter值不为“none”的元素。
8.perspective值不为“none”的元素。
9.isolation 属性被设置为 "isolate"的元素。
10.position: fixed
在 will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值(参考 这篇文章)
-we
bkit-overflow-scrolling 属性被设置 "touch"的元素
在层叠上下文中,其子元素同样也按照上面解释的规则进行层叠。 特别值得一提的是,其子元素的 z-index 值只在父级层叠上下文中有意义。子级层叠上下文被自动视为父级层叠上下文的一个独立单元。
总结:
给一个 HTML 元素定位和 z-index 赋值创建一个层叠上下文,(opacity 值不为 1 的也是相同)。
层叠上下文可以包含在其他层叠上下文中,并且一起创建一个有层级的层叠上下文。
每个层叠上下文完全独立于它的兄弟元素:当处理层叠时只考虑子元素。
每个层叠上下文是自包含的:当元素的内容发生层叠后,整个该元素将会在父层叠上下文中按顺序进行层叠。
Note: 层叠上下文的层级是 HTML 元素层级的一个层级,因为只有某些元素才会创建层叠上下文。可以这样说,没有创建自己的层叠上下文的元素将被父层叠上下文包含。
在这个例子中,每个被定位的元素都创建了独自的层叠上下文,因为他们被指定了定位属性和 z-index 属性。层叠上下文的层级如下:
Root
DIV #1
DIV #2
DIV #3
DIV #4
DIV #5
DIV #6
注意 DIV#4,DIV #5 和 DIV #6 是 DIV #3 的子元素,所以它们的层叠完全在 DIV #3 中被处理。一旦 DIV #3 中的层叠和渲染处理完成,DIV #3 元素作为一个整体传递给 root 元素,并相对兄弟元素层叠。
注意:
DIV #4 被渲染在 DIV #1 之下,因为 DIV #1 的 z-index (5) 在 root 元素的层叠上下文中生效,而 DIV #4 的 z-index (6) 在 DIV #3 的层叠上下文中生效。因此,DIV #4 在 DIV #1 之下,因为 DIV #4 归属于 z-index 值较低的 DIV #3 元素。
由此可得 DIV #2 (z-index 2) 被渲染在 DIV #5 (z-index 1) 之下,因为 DIV #5 归属于 z-index 较高的 DIV #3 元素。
DIV #3 的 z-index 值是 4,但是这个值独立于 DIV #4,DIV #5 和 DIV #6 的 z-index 值,因为他们从属于不同的层叠上下文。
分辨出层叠的元素在 Z 轴上的渲染顺序的一个简单方法是将它们想象成一系列的版本号,子元素是其父元素版本号之下的次要版本。通过这个方法我们可以轻松得看出为什么一个 z-index 为 1 的元素(DIV #5)层叠于一个 z-index 为 2 的元素(DIV #2)之上,而一个 z-index 为 6 的元素(DIV #4)层叠于 z-index 为 5 的元素(DIV #1)之下。在我们的例子中(依照最终渲染次序排列):
Root
DIV #2 - z-index 为 2
DIV #3 - z-index 为 4
DIV #5 - z-index 为 1,在一个 z-index 为 4 的元素内层叠,所以渲染次序为 4.1
DIV #6 - z-index 为 3,在一个 z-index 为 4 的元素内层叠,所以渲染次序为 4.3
DIV #4 - z-index 为 6,在一个 z-index 为 4 的元素内层叠,所以渲染次序为 4.6
DIV #1 - z-index 为 5
2.层叠顺序
当元素中没有具体的z-index属性时,元素的层叠按照如下顺序(从底置顶,即从浏览器到用户)