为什么伪元素背景色在与 transform 一起使用时会覆盖其父背景色?

Why pseudo element background color covered its parent background color when used with transform?

更新:这个问题被朋友标记为重复,但我认为答案仍然很有价值。我在重复的问题中查看了这些答案,没有人提到 transform-style: preserve-3d 可以在不创建新的堆叠上下文的情况下进行转换。所以这个问题比 z-index 的工作原理更具体。这也是关于转换如何工作的。


我试图在悬停在 div 元素上时添加一些动画。但是当我在 hover 中添加 transform 时,它的伪子元素的背景颜色覆盖了 div。似乎只有在使用 transform 时才会发生这种有线行为。我想知道这种行为背后的机制是什么。

在下面的codepen例子中,第一个是hover with transform,第二个是normal hover。

https://codepen.io/neirongkuifa/pen/PgaEZd

.container {
 width: 100px;
 height: 100px;
 background-color: red;
 position: relative;
  margin-bottom:100px;
}

.move:hover {
 transform: translateY(3px);
}

.changeColor:hover{
  background-color:white
}

.container::after {
 content: '';
 display: inline-block;
 position: absolute;
 top: 0;
 left: 0;
 background-color: green;
 width: 150px;
 height: 150px;
 z-index: -1;
}
<div class="container move">Content</div>
<div class="container changeColor">Content</div>

您正在创建一个新的堆栈上下文,而 z-index 的行为有所不同。

最好的解决方案是使用转换来处理所有事情。我在伪中添加了一个 transformZ negative 以将其向后移动,并在项目上添加了一个 preserve-ed 以使其工作:

.container {
    width: 100px;
    height: 100px;
    background-color: red;
    position: relative;
  margin-bottom:100px;
  transform-style: preserve-3D;   /*added*/
}

.move:hover {
    transform: translateY(3px);
}

.changeColor:hover{
  background-color:white
}

.container::after {
    content: '';
    display: inline-block;
    position: absolute;
    top: 0;
    left: 0;
    background-color: green;
    width: 150px;
    height: 150px;
    z-index: -1;
    transform: translateZ(-1px); /*added*/
}
<div class="container move">Content</div>
<div class="container changeColor">Content</div>