你知道 top-layer 吗?

1,690 阅读3分钟

本文正在参加「金石计划 . 瓜分6万现金大奖」

全文中 top-layer 等同于 顶层;Backdrop 等同于 背景。

背景

需求:在做一个需求,要求支持全屏 screenfull,还要求支持水印 watermark。

问题:在实现的过程中发现,当处于全屏的状态下的页面,水印消失了。

解决过程:打开了浏览器控制台去调试,尝试去给水印模块设置 z-index 属性,提高其层级。发现不管怎么设置都不起作用。又仔细去看了全屏的元素,发现在全屏状态下会多一个 top-layer 标识,同时还多一个::backdrop 伪元素。

好奇之心top-layer 这是什么?起的什么作用?全屏的原理和这个有关?

认识 top-layer

在浏览器窗口中,top-layer 位于其相关层 document 之上 ,并且每个 document 层都有一个相关联的top-layer。这意味着提升到 top-layer 的元素无需担心 z-indexDOM 层次结构。他们还得到了一个整洁的 ::backdrop 伪元素来玩。

比如:模态对话框需要出现在所有其他 DOM 内容之上,因此浏览器会自动在 “top-layer” 呈现此元素,而不是强迫作者手动与 z-index 作斗争。即使 z-index 最高,顶层元素也会出现在元素之上。

top-layer 可以描述为“最高堆叠层”。每个文档都有一个关联的视口,因此也有一个 top-layer。多个元素可以同时位于 top-layer。发生这种情况时,它们会堆叠在一起,最后一个在上面。换句话说,所有 top-layer 元素都放置在 top-layer后进先出(LIFO) 堆栈中。

目前,top-layer 元素有:pop-upsmodal dialogsfullscreen的元素。

全屏 API 规范有更多细节,因为 全屏是在 dialog支持 出现之前使用 top-layer 的一个很好的例子。

top-layer 有助于解决在 document 其余部分之上呈现内容的问题。

重要的几点内容:

  • top-layerdocument 流程之外。
  • z-indextop-layer 没有影响。
  • top-layer 中的每个元素都有一个可设置样式的 ::backdrop 伪元素。
  • 每个元素和 ::backdrop 生成一个新的堆叠上下文。
  • top-layer 中的元素按照它们在集合中出现的顺序堆叠。最后一个出现在顶部。如果要提升某个元素,请将其删除,然后重新添加。

::backdrop 伪元素

Backdrop 是一个与视口大小相同的框,在任何顶层元素的正下方进行渲染。::background 伪元素使得当元素位于顶层的最顶层时,可以隐藏、设置样式或完全隐藏元素下方的所有内容。

当将多个元素设置为 modal 时,浏览器会在最前面的元素下方以及其他全屏元素上方绘制 Backdrop。

每个顶层元素都有一个属于顶层堆栈的背景。这些背景设计为相互重叠,因此如果背景的不透明度不是 100%,则下面的背景是可见的。

如果只有顶层堆栈中的第一个背景需要可见,可以通过跟踪顶层堆栈中的项目标识符来实现。

如果添加的元素不是顶层的第一个元素,则将元素放入顶层时调用的函数将一个 hiddenBackdrop 类应用到::backdrop。当元素从顶层移除时,这个类被移除。

Chrome DevTools

Chrome DevTools 里边有对 top-layer 元素的支持(应该是 Chrome 105 版本之后支持的),以便我们可以检查调试 top-layer

36Yck7O77zDipSNGNNbB.avif

最后

这次做的全屏 screenfull + 水印 watermark 的需求,引起我去了解一下 top—layer,收获还是不少的,本文也是对 to-layer 初步认识。虽然最后那个问题解决并非因为 top-layer,但是也算是一种知识点储备,后续可能遇到。也是对 screenfull 原理的一种理解。