为什么具有z-index值的元素不能覆盖其子级? [英] Why can't an element with a z-index value cover its child?

查看:131
本文介绍了为什么具有z-index值的元素不能覆盖其子级?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天,经过数小时的调试,我很难学到了该规则:

Today after hours of debugging, I learned this rule the hard way:

如果父级的z-index值为任何值,则无论您如何更改子级的CSS,父级元素都永远无法覆盖(堆叠在其子级元素之上)

我如何才能通过逻辑理解这种行为?是规格吗?

How can I understand this behavior by logic? Is it in the specs?

.container {
  width: 600px;
  height: 600px;
  background-color: salmon;
  position: relative;
  z-index: 99;
  padding-top: 10px;
}

h1 {
  background-color: pink;
  position: relative;
  z-index: -1;
  font-family: monospace;
}

<div class="container">
  <h1>1. I can never be covered by parent if my z-index is positive.</h1>
  <h1>2. Even when my z-index is nagative, I still can never be covered if my parent has any z-index at all.</h1>
</div>

推荐答案

您需要了解两件重要的事情:绘制顺序和堆叠上下文.如果您参考规范,则可以找到绘制元素的方式和时间

There are two important things you need to know: the painting order and the stacking context. If you refer to the specification, you can find how and when elements are painted.

  1. 堆叠上下文是由定位后代带有负Z索引(不包括0)的Z索引顺序(最负的是第一个)然后是树顺序形成的.
  1. Stacking contexts formed by positioned descendants with negative z-indices (excluding 0) in z-index order (most negative first) then tree order.


  1. 按树顺序排列的所有已定位,不透明或转换后代,分为以下类别:
  1. All positioned, opacity or transform descendants, in tree order that fall into the following categories:
  1. 所有定位为"z-index:auto"或"z-index:0"的后代,以树顺序排列.


    由具有 z索引大于或等于1 的定位后代形成的
  1. 堆叠上下文,按z索引顺序(最小的顺序为小),然后是树顺序.
  1. Stacking contexts formed by positioned descendants with z-indices greater than or equal to 1 in z-index order (smallest first) then tree order.

由此可见,我们首先在步骤(3)绘制具有负z-index的元素,然后在步骤(8)绘制具有z-index等于0的元素,最后在步骤3绘制具有正z-index的元素. (9),这是合乎逻辑的.我们还可以阅读规范的另一部分:

It's clear from this that we first paint elements with negative z-index at step (3), then the one with z-index equal to 0 at step (8), and finally the ones with positive z-index at step (9), which is logical. We can also read in another part of the specification:

每个框都属于一个堆叠上下文.给定堆叠上下文中的每个盒子都有一个整数堆叠级别,这是它在z轴上相对于同一堆叠上下文中的其他盒子的位置.具有较高堆栈级别的框始终在具有较低堆栈级别的框前面格式化.箱子的堆叠高度可能为负.在堆叠上下文中具有相同堆叠级别的框将根据文档树的顺序从下到上堆叠.

Each box belongs to one stacking context. Each box in a given stacking context has an integer stack level, which is its position on the z-axis relative to other boxes in the same stacking context. Boxes with greater stack levels are always formatted in front of boxes with lower stack levels. Boxes may have negative stack levels. Boxes with the same stack level in a stacking context are stacked bottom-to-top according to document tree order.

建立本地堆栈上下文的元素会生成一个具有两个堆栈级别的框:一个用于它创建的堆栈上下文(始终为0),另一个用于它所属的堆栈上下文(由z-index属性赋予)

An element that establishes a local stacking context generates a box that has two stack levels: one for the stacking context it creates (always 0) and one for the stacking context to which it belongs (given by the z-index property).


要了解何时绘制每个元素,您需要了解此堆栈上下文(由定义)中的其堆栈上下文其堆栈级别.您还需要知道该元素是否建立了堆栈上下文.这是棘手的部分,因为设置z-index可以做到这一点:


To understand when each element will be painted you need to know its stacking context and its stack level inside this stacking context (defined by z-index). You also need to know whether that element establishes a stacking context. This is the tricky part, because setting z-index will do this:

对于定位框,z-index属性指定:

For a positioned box, the z-index property specifies:

  1. 当前堆栈上下文中框的堆栈级别.
  2. 盒子是否建立了堆叠环境

值具有以下含义:

<integer>

此整数是当前堆栈上下文中生成的框的堆栈级别.该框还建立新的堆叠上下文.

This integer is the stack level of the generated box in the current stacking context. The box also establishes a new stacking context.

auto

在当前堆栈上下文中生成的框的堆栈级别为0.框不会建立新的堆栈上下文,除非它是根元素.

The stack level of the generated box in the current stacking context is 0. The box does not establish a new stacking context unless it is the root element.


现在,我们拥有所有信息,可以更好地理解每种情况.如果父元素的z-index值不是auto,那么它将创建一个堆栈上下文,因此子元素将被绘制在其z-index的任何内部(负数或正数).子元素的z-index会简单地告诉我们父元素(这是您的第二点)中的绘画顺序.


Now we have all the information to better understand each case. If the parent element has a z-index value of something other than auto, then it will create a stacking context, thus the child element will be painted inside whatever their z-index is (negative or positive). The z-index of the child element will simply tell us the order of painting inside the parent element (this covers your second point).

现在,如果仅子元素具有正数z-index,而我们在父元素上未设置任何内容,则考虑绘制顺序,稍后(步骤(9)中)将绘制子对象,而在步骤(9)中父元素将被绘制. 8).在上面绘制父级的唯一逻辑方法是增加z-index,但是这样做会使我们陷入前一种情况,即父级将建立一个堆栈上下文,而子元素将属于该上下文.

Now, if only the child element has a positive z-index and we set nothing on the parent element, then considering the painting order, the child will be painted later (in step (9)) and the parent in step (8). The only logical way to paint the parent above is to increase the z-index, but doing this will make us fall into the previous case where the parent will establish a stacking context and the child element will belong to it.

在为孩子设置肯定 z-index时,没有没有办法将父对象放在子元素上方.如果我们将z-index设置为不同于auto的父元素(正数或负数),也没有没有办法使父项高于子项. 1

There is no way to have the parent above a child element when setting a positive z-index to the child. Also there is no way to have the parent above the child if we set a z-index to the parent element different from auto (either positive or negative).1

我们唯一可以在其父级以下拥有一个子级的情况是在子元素上设置一个负数z-index并将父级保持在z-index: auto,因此该子级将不会创建堆叠上下文并遵循绘制顺序孩子将被首先涂漆.

The only case where we can have a child below its parent is to set a negative z-index on the child element and keep the parent at z-index: auto, thus this one will not create a stacking context and following the painting order the child will be painted first.

除了z-index,还有

In addition to z-index, there are other properties that create a stacking context. In case you face an expected stacking order, you need to consider those properties, too, in order to see if there is a stacking context created.

我们可以从上面得出的一些重要事实:

Some important facts that we can conclude from the above:

  1. 堆栈上下文可以包含在其他堆栈上下文中,并一起创建堆栈上下文的层次结构.
  2. 每个堆叠上下文完全与兄弟姐妹无关:处理堆叠时仅考虑后代元素.
  3. 每个堆叠上下文都是自包含的:堆叠元素的内容之后,将按照父堆叠上下文的堆叠顺序考虑整个元素. 参考
  1. Stacking contexts can be contained in other stacking contexts, and together create a hierarchy of stacking contexts.
  2. Each stacking context is completely independent of its siblings: only descendant elements are considered when stacking is processed.
  3. Each stacking context is self-contained: after the element's contents are stacked, the whole element is considered in the stacking order of the parent stacking context. ref


1 :如果我们考虑使用3D变换,则有一些骇人听闻的方法.


1: there is some hacky ways if we consider the use of 3D transformation.

示例中有一个元素位于其父元素下,即使该元素指定了z-index.

Example with an element going under its parent element even if this one has a z-index specified.

.box {
  position:relative;
  z-index:0;
  height:80px;
  background:blue;
  transform-style: preserve-3d; /* This is important */
}
.box > div {
  margin:0 50px;
  height:100px;
  background:red; 
  z-index:-1; /* this will do nothing */
  transform:translateZ(-1px); /* this will do the magic */
}

<div class="box">
  <div></div>
</div>

另一个示例,我们可以在另一个堆叠上下文中将一个元素放置在两个元素之间:

Another example where we can place an element between two elements in another stacking context:

.box {
  position: relative;
  z-index: 0;
  height: 80px;
  background: blue;
}

.box>div {
  margin: 0 50px;
  height: 100px;
  background: red;
  z-index: 5;
  transform: translateZ(2px);
}

.outside {
  height: 50px;
  background: green;
  margin: -10px 40px;
  transform: translateZ(1px);
}

body {
  transform-style: preserve-3d;
}

<div class="box">
  <div></div>
</div>

<div class="outside"></div>

我们还可以像下面这样设置 crazy 的堆叠顺序:

We can also have some crazy stacking order like below:

.box {
  width: 100px;
  height: 100px;
  position: absolute;
}

body {
  transform-style: preserve-3d;
}

<div class="box" style="top:100px;left:50px;background:red;"></div>
<div class="box" style="top: 50px;left: 115px;background:blue;"></div>
<div class="box" style="top: 101px;left: 170px;background:green;"></div>
<div class="box" style="top: 175px;left: 115px;background:purple;transform: rotateY(-1deg);"></div>

我们应该注意,由于transform-styleperspectivetransform将影响position:absolute/fixed元素,因此使用此类 hack 可能会有一些副作用.相关:父母的CSS过滤器会破坏孩子的位置

We should note that using such hack may have some side effect due to the fact that transform-style, perspective and transform will affect position:absolute/fixed element. Related: CSS-Filter on parent breaks child positioning

这篇关于为什么具有z-index值的元素不能覆盖其子级?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆