Open henry-fun opened 5 years ago
原文地址: https://blog.logrocket.com/how-css-works-creating-layers-with-z-index-6a20afe1550e 原文作者: Benjamin Johnson
原文地址: https://blog.logrocket.com/how-css-works-creating-layers-with-z-index-6a20afe1550e
原文作者: Benjamin Johnson
这篇文章是"How CSS workd"系列文章中的第三篇(深入探讨CSS基本构建模块的系列文章,这些基本构建模块有时会让人感觉像是黑魔法)。无论你如何编写你的css代码,知道样式表的运行原理总是极好的,这样你才能编写出高效的、可伸缩性css代码。
下面是系列文章中的前两篇:
今天我们研究css的另一个黑魔法 — z-index,耍z-index,通常感觉像是往墙面上扔一个更高的数字,然后看看是什么效果。
但如果我们试着剥离z-index上的层,看看管理他们的规则呢,我们会发现它并不像我们想象的那么可怕。
说到底,我们在浏览器中使用的屏幕是一组由像素组成的二维平面,但如果你经常上网,你可能会经常体会到"三维”世界,例如,你可以单击一个按钮打开一个 modal,或者触发一个tool-tip
如果你假设用户正在看屏幕,并想象屏幕是三维世界的入口,你可以开启浏览器中的三维空间呈现,首先,我们把该空间想象成一个房间,那么"最远"的"墙"就被称为"画布 canvas"
当在屏幕是绘制像素时,浏览器首先会确保绘制距画布最近(或最远)的像素,然后,他将渐进的将元素"更接近"用户,并覆盖以前绘制的像素
z-index属性表示元素在三维浏览器视觉中绘制的顺序,默认情况下,所有元素的 z-index 皆为0,浏览器按照 DOM 顺序进行绘制,然而实际上,z-index 为我们提供了何时绘制元素的细节控制,通过指定较高的 z-index,我们可以使绘制出的元素"更接近"用户,如果我们指定一个较低的(或负值)z-index,我们可以使绘制出的元素更接近画布。
在深入研究 CSS 的位置和布局规范时,我发现了这个有用的图片,它可以直观的显示出 z-index 层叠对用户视觉的影响。
具有较高 z-index的元素看起来"更接近"用户
z-index
如果我们只看到 z-index 的这种特性,我们很容易被诱导认为它就是 z-index 的全部知识了:更高的 z-index就更接近用户,更小的 z-index 则更远离,然而,z-index 还有一些细节常被混淆。
z-index 的第一个注意点是它必须在被设定了 position 属性元素上时才会生效,这意味着,z-index 只有在position 设置为除 static 属性上的元素上时,它才能更改层叠顺序,在元素没有设置任何 position 的情况下,z-index 将不会起任何作用。
position
static
当我们探讨到 z-index 的第二个注意点时,z-index 变得更加让人困惑了,因为 z-index 只适用于层叠环境中的元素。
层叠上下文涉及到了 HTML 节点和它的所有子节点,HTML 元素位于层叠上下文的 root 级别,它可以被称为根层叠。
HTML
文档的默认层叠上下文(或"根层叠上下文")将 HTML 元素标记为其"根层叠",并且默认情况下,所有元素都属于此根层叠上下文,但是,任何元素节点也可以是其"局部层叠上下文"中的根层叠。
你可以通过以下几种方法将元素指定为新的局部层叠上下文的根层叠:
absolute
relative
auto
position: fixed
position: sticky
opacity
transform
will-change
如果你想看到更多创建层叠环境的方法,请在 MDN上查看该文章
作为例子,让我们想象 HTML的三个树节点,将它们想想为三个层叠,在下图中,每个层叠的底部是HTML节点,子元素堆叠在其上(有点像 HTML 树的颠倒表示),让我们假设这些元素都是 body 标签的直接子节点。
如果我们在浏览器中预览这些HTML元素,它将表示为如下:
注意到什么有趣的事情了吗?
首先,为什么blue-child-1低于其它标签?它的z-index是1000000,它不是应该在最上面吗?
blue-child-1
此外,为什么green-child-1为什么显示在所有元素的顶部,及时它的z-index为2,我们不是说更高级别的z-index胜过更低级别的z-index吗?
green-child-1
让我们从green-child-1元素开始,因为它的父元素green-parent的z-index为999,我们期望green-parent元素也高于其它元素,但如果我们回想一下使用 z-index的第一个警告:它对静态定位的元素没有影响,这意味着green-child-1是层叠上下文的一部分,它是根据red-parent和blue-parent(根层叠中唯一的其它两个元素)进行测量的,它的z-index比这两个更高,所有它显示在顶部。
green-parent
red-parent
blue-parent
了解red-parent和blue-parent各自创建的局部层叠环境也有助于我们了解为什么blue-child-2显示在red-parent之下,即使其z-index更高,由于z-index仅控制元素在其局部层叠上下文中的位置,因此blue-child-2肯定要高于blue-parent的子级。但是red-parent的z-index要高于blue-parent,无论它们的z-index是多少,red-parent内部的所有元素都将比blue-parent元素显示出更高的 z-index
blue-child-2
为了使blue-child-2显示在red-parent之上,我们实际上必须要更改HTML结构,使得blue-hild-2脱离它当前的局部层叠上下文环境,并使其进入根层叠上下文(或者至少是位于red-parent之上的层叠上下文)。
blue-hild-2
在大型web应用中,这样变更通常是很麻烦切危险的,特别是当你试图管理语义化的HTML结构或模块化组件结构时。
你经常看到许多组件库通过将元素添加到 body 标签中,而不是包含在你自己定义的组件中以此来实现更高曾经的UI 组件(如 tool-tips和modal),这么做可以在很大程度上避开这些层叠上限文"陷阱",这么做也可以确保严重依赖层叠的组件的z-index始终处于根层叠上下文环境中,因此它们可以将z-index设为值1000,并相信他将显示在大多数元素的顶部。
在一些情况下,使用 z-index 可能很麻烦,但是当我们知道它的底层原理及工作规则时,我们会发现它的行为实际上是相当可预测的,我想99%的关于z-index的混淆都源自我们在上面讨论的那两个警告的误解
作为复习,我在这里再强调一遍:
我希望你以后在遇到多层 ui 导致的各种陷阱时,了解 z-index的内部结构会给你带来信心,我知道,研究z-index和层叠系统对于我们更好的开发ui会更有帮助。
红蓝绿那张图及解释看的真的很混乱
介绍
这篇文章是"How CSS workd"系列文章中的第三篇(深入探讨CSS基本构建模块的系列文章,这些基本构建模块有时会让人感觉像是黑魔法)。无论你如何编写你的css代码,知道样式表的运行原理总是极好的,这样你才能编写出高效的、可伸缩性css代码。
下面是系列文章中的前两篇:
今天我们研究css的另一个黑魔法 — z-index,耍z-index,通常感觉像是往墙面上扔一个更高的数字,然后看看是什么效果。
但如果我们试着剥离z-index上的层,看看管理他们的规则呢,我们会发现它并不像我们想象的那么可怕。
究竟什么是z-indx?
说到底,我们在浏览器中使用的屏幕是一组由像素组成的二维平面,但如果你经常上网,你可能会经常体会到"三维”世界,例如,你可以单击一个按钮打开一个 modal,或者触发一个tool-tip
如果你假设用户正在看屏幕,并想象屏幕是三维世界的入口,你可以开启浏览器中的三维空间呈现,首先,我们把该空间想象成一个房间,那么"最远"的"墙"就被称为"画布 canvas"
当在屏幕是绘制像素时,浏览器首先会确保绘制距画布最近(或最远)的像素,然后,他将渐进的将元素"更接近"用户,并覆盖以前绘制的像素
z-index属性表示元素在三维浏览器视觉中绘制的顺序,默认情况下,所有元素的 z-index 皆为0,浏览器按照 DOM 顺序进行绘制,然而实际上,z-index 为我们提供了何时绘制元素的细节控制,通过指定较高的 z-index,我们可以使绘制出的元素"更接近"用户,如果我们指定一个较低的(或负值)z-index,我们可以使绘制出的元素更接近画布。
在深入研究 CSS 的位置和布局规范时,我发现了这个有用的图片,它可以直观的显示出 z-index 层叠对用户视觉的影响。
具有较高
z-index
的元素看起来"更接近"用户如果我们只看到
z-index
的这种特性,我们很容易被诱导认为它就是 z-index 的全部知识了:更高的 z-index就更接近用户,更小的 z-index 则更远离,然而,z-index 还有一些细节常被混淆。z-index 的第一个注意点是它必须在被设定了
position
属性元素上时才会生效,这意味着,z-index
只有在position
设置为除static
属性上的元素上时,它才能更改层叠顺序,在元素没有设置任何position
的情况下,z-index 将不会起任何作用。层叠上下文介绍
当我们探讨到 z-index 的第二个注意点时,
z-index
变得更加让人困惑了,因为z-index
只适用于层叠环境中的元素。层叠上下文涉及到了
HTML
节点和它的所有子节点,HTML
元素位于层叠上下文的 root 级别,它可以被称为根层叠。文档的默认层叠上下文(或"根层叠上下文")将
HTML
元素标记为其"根层叠",并且默认情况下,所有元素都属于此根层叠上下文,但是,任何元素节点也可以是其"局部层叠上下文"中的根层叠。你可以通过以下几种方法将元素指定为新的局部层叠上下文的根层叠:
position
为absolute
或relative
或其它任何除了auto
属性上设置z-index
position: fixed
或position: sticky
opacity
属性值小于1transform
或will-change
如果你想看到更多创建层叠环境的方法,请在 MDN上查看该文章
作为例子,让我们想象
HTML
的三个树节点,将它们想想为三个层叠,在下图中,每个层叠的底部是HTML
节点,子元素堆叠在其上(有点像 HTML 树的颠倒表示),让我们假设这些元素都是 body 标签的直接子节点。如果我们在浏览器中预览这些HTML元素,它将表示为如下:
注意到什么有趣的事情了吗?
首先,为什么
blue-child-1
低于其它标签?它的z-index
是1000000,它不是应该在最上面吗?此外,为什么
green-child-1
为什么显示在所有元素的顶部,及时它的z-index
为2,我们不是说更高级别的z-index胜过更低级别的z-index吗?让我们从
green-child-1
元素开始,因为它的父元素green-parent
的z-index为999,我们期望green-parent
元素也高于其它元素,但如果我们回想一下使用 z-index的第一个警告:它对静态定位的元素没有影响,这意味着green-child-1
是层叠上下文的一部分,它是根据red-parent
和blue-parent
(根层叠中唯一的其它两个元素)进行测量的,它的z-index比这两个更高,所有它显示在顶部。了解
red-parent
和blue-parent
各自创建的局部层叠环境也有助于我们了解为什么blue-child-2
显示在red-parent
之下,即使其z-index
更高,由于z-index
仅控制元素在其局部层叠上下文中的位置,因此blue-child-2
肯定要高于blue-parent
的子级。但是red-parent
的z-index
要高于blue-parent
,无论它们的z-index
是多少,red-parent
内部的所有元素都将比blue-parent
元素显示出更高的z-index
为了使
blue-child-2
显示在red-parent
之上,我们实际上必须要更改HTML结构,使得blue-hild-2
脱离它当前的局部层叠上下文环境,并使其进入根层叠上下文(或者至少是位于red-parent
之上的层叠上下文)。在大型web应用中,这样变更通常是很麻烦切危险的,特别是当你试图管理语义化的HTML结构或模块化组件结构时。
你经常看到许多组件库通过将元素添加到 body 标签中,而不是包含在你自己定义的组件中以此来实现更高曾经的UI 组件(如 tool-tips和modal),这么做可以在很大程度上避开这些层叠上限文"陷阱",这么做也可以确保严重依赖层叠的组件的z-index始终处于根层叠上下文环境中,因此它们可以将z-index设为值1000,并相信他将显示在大多数元素的顶部。
结论
在一些情况下,使用
z-index
可能很麻烦,但是当我们知道它的底层原理及工作规则时,我们会发现它的行为实际上是相当可预测的,我想99%的关于z-index
的混淆都源自我们在上面讨论的那两个警告的误解作为复习,我在这里再强调一遍:
z-index
仅用于除 static 元素外的具有position
的元素z-index
仅适用于元素在其所属的层叠上下文中的位置我希望你以后在遇到多层 ui 导致的各种陷阱时,了解
z-index
的内部结构会给你带来信心,我知道,研究z-index
和层叠系统对于我们更好的开发ui会更有帮助。